File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / lcd.cpp
Revision 1.1.1.15 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:00 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

//
// nono
// Copyright (C) 2020 nono project
// Licensed under nono-license.txt
//

//
// LCD (HD44780)
//

#include "lcd.h"
#include "monitor.h"
#include "uimessage.h"

// コンストラクタ
LCDDevice::LCDDevice()
	: inherited(OBJ_LCD)
{
	monitor = gMonitorManager->Regist(ID_MONITOR_LCD, this);
	monitor->SetCallback(&LCDDevice::MonitorScreen);
	monitor->SetSize(67, 3);
}

// デストラクタ
LCDDevice::~LCDDevice()
{
}

// 初期化
bool
LCDDevice::Init()
{
	uimessage = gMainApp.GetUIMessage();

	return true;
}

// リセット
void
LCDDevice::ResetHard(bool poweron)
{
	// とりあえずモニタ画面での表示を消す
	memset(ddram, 0x20, sizeof(ddram));
	// XXX not yet
	// CGRAM とか信号線とか

	SetAddr(0, false);

	uimessage->Post(UIMessage::LCD);
}

// 電源オフ
void
LCDDevice::PowerOff()
{
	// XXX 電源オフは色を落としたほうがいい
	memset(ddram, 0x20, sizeof(ddram));
	uimessage->Post(UIMessage::LCD);
}

void
LCDDevice::SetRW(bool val)
{
	rw = val;
	putlog(2, "R/W = %c", val ? 'R' : 'W');
}

void
LCDDevice::SetRS(bool val)
{
	rs = val;
	putlog(2, "RS = %u", rs);
}

void
LCDDevice::SetE(bool val)
{
	en = val;
	putlog(2, "E = %u", en);
}

// E, RS, R/W 線の状態を取得する (PIO1 のポートC 読み込み用)
uint8
LCDDevice::Get() const
{
	return (en ? 0x80 : 0)
		 | (rs ? 0x40 : 0)
		 | (rw ? 0x20 : 0);
}

// 現在のアドレスでデータレジスタにラッチ
void
LCDDevice::LatchData()
{
	if (addr_is_cgram) {
		// cgram は 5 bit 有効で左詰めされている
		data_reg = cgram[addr_counter] >> 3;
	}  else {
		data_reg = ddram[addr_counter];
	}
}

// アドレスカウンタを設定
void
LCDDevice::SetAddr(uint addr, bool is_cgram)
{
	// アドレスカウンタをセットするとデータレジスタにラッチされる
	addr_counter = addr;
	addr_is_cgram = is_cgram;
	LatchData();
}

// アドレスカウンタを次へ進める
void
LCDDevice::NextAddr()
{
	// アドレス更新について。
	// DDRAM は各行 0x27 までしか存在していないが、stride が 0x40 バイト。
	// XXX CGRAM が折り返すかどうかは分からないがそのまま DDRAM 領域に
	// 行っても困ると思うのでとりあえず。

	if (addr_is_cgram) {
		if (addr_inc) {
			addr_counter++;
		} else {
			addr_counter--;
		}
		addr_counter &= 0x3f;
	} else {
		// 2 行モードしかサポートしていない
		if (addr_inc) {
			addr_counter++;
			if (addr_counter == 0x28) {			// DDRAM 1行目
				addr_counter = 0x40;
			} else if (addr_counter == 0x68) {	// DDRAM 2行目
				addr_counter = 0x0;
			}
		} else {
			if (addr_counter == 0x0) {			// DDRAM 1行目
				addr_counter = 0x68;
			} else if (addr_counter == 0x40) {	// DDRAM 2行目
				addr_counter = 0x28;
			}
			addr_counter--;
		}
	}
	LatchData();
}

uint8
LCDDevice::Read()
{
	if (en == false || rw == false) {
		// ハイインピーダンス
		return 0xff;
	}

	if (rs == false) {
		// ステータスレジスタの読み込み
		// B A A A A A A A
		// | +-+-+-+-+-+-+-- アドレスカウンタ
		// +---------------- ビジーフラグ %1=BUSY

		// XXX ビジーは未実装
		return addr_counter;
	} else {
		// データレジスタの読み込み
		uint8 rv = data_reg;
		NextAddr();
		return rv;
	}
}

void
LCDDevice::Write(uint8 data)
{
	if (en == false) {
		// ハイインピーダンス
		return;
	}
	if (rw == true) {
		// LCD はドライブ、PIOもドライブ。ショートが発生して燃える。
		// たまたま値が一致したときだけセーフ。
		putlog(0, "LCD will short out.");
		return;
	}

	if (rs == false) {
		// コマンド書き込み

		if ((data & 0x80)) {
			SetAddr(data & 0x7f, false);
			putlog(1, "DDRAM Address <- $%02x", addr_counter);
		} else if ((data & 0x40)) {
			SetAddr(data & 0x3f, true);
			putlog(1, "CGRAM Address <- $%02x", addr_counter);
		} else if ((data & 0x20)) {
			// ファンクション・セット
			// 0x38 (8ビットバス、2行表示、8ライン/行)モードのみサポート
			if (data != 0x38) {
				putlog(0, "Write Command $%02x Function Set (NOT IMPLEMENTED)",					data);
			}
		} else if ((data & 0x10)) {
			// カーソル移動
			putlog(0, "Write Command $%02x Move Cursor (NOT IMPLEMENTED)",
				data);
		} else if ((data & 0x08)) {
			// 表示ON/OFF
			// 文字表示 ON/OFF のみサポート
			disp_char = (data & 0x04);
			// XXX それ以外は未サポート
		} else if ((data & 0x04)) {
			// エントリモード
			addr_inc = (data & 0x02);
			// XXX 表示シフトは未サポート
		} else if ((data & 0x02)) {
			// カーソルホーム
			// DDRAM アドレス 0 をセット
			SetAddr(0, false);
		} else if ((data & 0x01)) {
			// 表示クリア
			memset(ddram, 0x20, sizeof(ddram));
			// DDRAM アドレス 0 をセット
			SetAddr(0, false);
			uimessage->Post(UIMessage::LCD);
		} else {
			// $00 が書き込まれるんだけど、データシートにはないんだよね。
			// 無視していいかな。
			putlog(2, "Write undefined $%02x", data);
		}
	} else {
		// データ書き込み
		if (addr_is_cgram) {
			// cgram は 5 bit 有効で左詰めで格納
			cgram[addr_counter] = data << 3;
			putlog(1, "CGRAM Data $%02x <- $%02x",
				addr_counter, data);
		} else {
			ddram[addr_counter] = data;
			putlog(1, "DDRAM Data X=%2u Y=%u <- $%02x",
				addr_counter % 0x40, addr_counter / 0x40, data);
		}
		NextAddr();
		uimessage->Post(UIMessage::LCD);
	}
}

// PIO1 からのピーク用
uint8
LCDDevice::Peek() const
{
	if (en == false || rw == false) {
		// XXX どうなるんだろ
		return 0xff;
	}
	if (rs == false) {
		// ステータスレジスタをピークする
		// XXX ビジーは未実装
		return addr_counter;
	} else {
		// データレジスタをピークする
		return data_reg;
	}
	return 0xff;
}

void
LCDDevice::MonitorScreen(Monitor *, TextScreen &screen)
{
	char buf[17];

	// 0         1         2         3         4         5         6
	// 01234567890123456789012345678901234567890123456789012345678901234567
	// RW=R  RS=0  E=0
	// 00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f |0123456789abcdef|
	// 00 01 02 03 04 05 06 07  08 09 0a 0b 0c 0d 0e 0f |0123456789abcdef|

	screen.Clear();
	screen.Print(0, 0, "RW=%c  RS=%u  E=%u", rw ? 'R' : 'W', rs, en);

	for (int y = 0; y < 2; y++) {
		memcpy(buf, &ddram[y * 0x40], 16);
		buf[16] = '\0';
		// 16進を表示する端から文字ダンプ用に加工していく
		for (int x = 0; x < 16; x++) {
			screen.Print(x * 3 + (x / 8), y + 1, "%02x", buf[x]);
			if (buf[x] < 0x20 || buf[x] > 0x7e) {
				buf[x] = '.';
			}
		}
		screen.Print(49, y + 1, "|%-16s|", buf);
	}
}

// CGROM は ROM A00 版のみ考慮する (A02 版との共存は今の所考えない)。
// A00 版は以下のような配置になっている。
//
//      +0+1+2+3+4+5+6+7+8+9+a+b+c+d+e+f
// 0x00 <------------ CGRAM ----------->
// 0x10
// 0x20   ! " # $ % & ' ( ) * + , - . /
// 0x30 0 1 2 3 4 5 6 7 8 9 : ; < = > ?
// 0x40 @ A B C D E F G H I J K L M N O
// 0x50 P Q R S T U V W X Y Z [ \ ] ^ _
// 0x60 ` a b c d e f g h i j k l m n o
// 0x70 p q r s t u v w x y z { | } →←
// 0x80
// 0x90
// 0xa0   。「」、・ヲァィゥェォャュョッ
// 0xb0 ーアイウエオカキクケコサシスセソ
// 0xc0 タチツテトナニヌネノハヒフヘホマ
// 0xd0 ミムメモヤユヨラリルレロワン゛゜
// 0xe0 <---- 5x10 ギリシャ文字など --->
// 0xf0 <---- 5x10 ギリシャ文字など --->
//
// 0x00 〜 0x07 は 8文字の CGRAM で、0x08 〜 0x0f には同じものが見える。
// 0x20〜0x7f と 0xa0〜0xdf までが 5x7 フォント、
// 0xe0〜0xff は 5x7 フォントと 5x10 フォントが混在している。
// 5x7 フォントは、メモリとしては 5x8 分(8バイト) を使用し、一番下のラインを
// 常に空白としておく (LCD の1行自体が 5x8 で構成されており、一番下が
// カーソル用に予約されているため)。
// 一方 5x10 フォントのカーソルはこのフォントの一つ下に表示するので 5x11
// フォントのうち一番下のラインがカーソル用とも言える。5x10 モードはサポート
// しないので、サイズを揃えるため上から 5x8 分のデータだけを保持することにする。
// (5x10 モードをサポートする時になんとかすること)
//
// 空き領域が多いこと、どのみち CGRAM 部分を考慮する必要があること、それと
// もし 5x10 モードをサポートする場合には途中でライン数が変わることなどから、
// フォントデータの取得は生データに直接アクセスさせるのではなく、1文字ずつ
// フォントデータのアドレスを返す方式にする。

// 文字コード ch のフォントデータ(の先頭アドレス) を取得する。
//
// 連続する 8 バイトがフォントデータで、下位側(右側) 5ビットのみ有効。
// 9バイト目が次の文字の1バイト目であることは保証していないので必ず1文字ごと
// に呼び出すこと。また CGRAM 領域のように動的に変化する場合もあるため
// 呼び出し側でこの読み出し値をキャッシュしないこと。
const uint8 *
LCDDevice::GetFont(uint ch) const
{
	// CGRAM 部分
	if (ch < 0x10) {
		ch &= 0x07;
		return &cgram[ch * 8];
	}

	if (ch < 0x20) {
		return &CGROM[0];	// space
	}

	// ASCII 部分
	if (ch < 0x80) {
		return &CGROM[(ch - 0x20) * 8];
	}

	if (ch < 0xa0) {
		return &CGROM[0];	// space
	}

	// カナ以降
	return &CGROM[(ch - 0xa0 + 0x60) * 8];
}

// MSB 側 5 ビットに詰める
#define B(x)	(0b##x##000)

/*static*/ const uint8 LCDDevice::CGROM[12 * 16 * 8] =
{
	B(00000),			// 0x20 space
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00100),			// 0x21 !
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00000),
	B(00100),
	B(0),

	B(01010),			// 0x22 "
	B(01010),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(01010),			// 0x23 #
	B(01010),
	B(11111),
	B(01010),
	B(11111),
	B(01010),
	B(01010),
	B(0),

	B(00100),			// 0x24 $
	B(01110),
	B(10100),
	B(01110),
	B(00101),
	B(01110),
	B(00100),
	B(0),

	B(11000),			// 0x25 %
	B(11001),
	B(00010),
	B(00100),
	B(01011),
	B(10011),
	B(00000),
	B(0),

	B(01100),			// 0x26 &
	B(10010),
	B(10100),
	B(01000),
	B(10100),
	B(10010),
	B(01101),
	B(0),

	B(01100),			// 0x27 '
	B(00100),
	B(01000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00010),			// 0x28 (
	B(00100),
	B(01000),
	B(01000),
	B(01000),
	B(00100),
	B(00010),
	B(0),

	B(01000),			// 0x29 )
	B(00100),
	B(00010),
	B(00010),
	B(00010),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0x2a *
	B(00100),
	B(10101),
	B(01110),
	B(10101),
	B(00100),
	B(00000),
	B(0),

	B(00000),			// 0x2b +
	B(00100),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(00000),
	B(0),

	B(00000),			// 0x2c ,
	B(00000),
	B(00000),
	B(00000),
	B(01100),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0x2d -
	B(00000),
	B(00000),
	B(11111),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0x2e .
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(01100),
	B(01100),
	B(0),

	B(00000),			// 0x2f /
	B(00001),
	B(00010),
	B(00100),
	B(01000),
	B(10000),
	B(00000),
	B(0),

	B(01110),			// 0x30 0
	B(10001),
	B(10011),
	B(10101),
	B(11001),
	B(10001),
	B(01110),
	B(0),

	B(00100),			// 0x31 1
	B(01100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(01110),
	B(0),

	B(01110),			// 0x32 2
	B(10001),
	B(10001),
	B(00010),
	B(00100),
	B(01000),
	B(11111),
	B(0),

	B(11111),			// 0x33 3
	B(00010),
	B(00100),
	B(01110),
	B(00001),
	B(10001),
	B(01110),
	B(0),

	B(00010),			// 0x34 4
	B(00110),
	B(01010),
	B(10010),
	B(11111),
	B(00010),
	B(00010),
	B(0),

	B(11111),			// 0x35 5
	B(10000),
	B(10000),
	B(11110),
	B(00001),
	B(10001),
	B(01110),
	B(0),

	B(00110),			// 0x36 6
	B(01000),
	B(10000),
	B(11110),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(11111),			// 0x37 7
	B(00001),
	B(00010),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(01110),			// 0x38 8
	B(10001),
	B(10001),
	B(01110),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(01110),			// 0x39 9
	B(10001),
	B(10001),
	B(01111),
	B(00001),
	B(00010),
	B(01100),
	B(0),

	B(00000),			// 0x3a :
	B(01100),
	B(01100),
	B(00000),
	B(01100),
	B(01100),
	B(00000),
	B(0),

	B(00000),			// 0x3b ;
	B(01100),
	B(01100),
	B(00000),
	B(01100),
	B(00100),
	B(01000),
	B(0),

	B(00010),			// 0x3c <
	B(00100),
	B(01000),
	B(10000),
	B(01000),
	B(00100),
	B(00010),
	B(0),

	B(00000),			// 0x3d =
	B(00000),
	B(11111),
	B(00000),
	B(11111),
	B(00000),
	B(00000),
	B(0),

	B(01000),			// 0x3e >
	B(00100),
	B(00010),
	B(00001),
	B(00010),
	B(00100),
	B(01000),
	B(0),

	B(01110),			// 0x3f ?
	B(10001),
	B(00001),
	B(00010),
	B(00100),
	B(00000),
	B(00100),
	B(0),

	B(01110),			// 0x40 @
	B(10001),
	B(00001),
	B(01101),
	B(10101),
	B(10101),
	B(01110),
	B(0),

	B(01110),			// 0x41 A
	B(10001),
	B(10001),
	B(10001),
	B(11111),
	B(10001),
	B(10001),
	B(0),

	B(11110),			// 0x42 B
	B(10001),
	B(10001),
	B(11110),
	B(10001),
	B(10001),
	B(11110),
	B(0),

	B(01110),			// 0x43 C
	B(10001),
	B(10000),
	B(10000),
	B(10000),
	B(10001),
	B(01110),
	B(0),

	B(11100),			// 0x44 D
	B(10010),
	B(10001),
	B(10001),
	B(10001),
	B(10010),
	B(11100),
	B(0),

	B(11111),			// 0x45 E
	B(10000),
	B(10000),
	B(11110),
	B(10000),
	B(10000),
	B(11111),
	B(0),

	B(11111),			// 0x46 F
	B(10000),
	B(10000),
	B(11110),
	B(10000),
	B(10000),
	B(10000),
	B(0),

	B(01110),			// 0x47 G
	B(10001),
	B(10000),
	B(10011),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(10001),			// 0x48 H
	B(10001),
	B(10001),
	B(11111),
	B(10001),
	B(10001),
	B(10001),
	B(0),

	B(01110),			// 0x49 I
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(01110),
	B(0),

	B(00111),			// 0x4a J
	B(00010),
	B(00010),
	B(00010),
	B(10010),
	B(10010),
	B(01100),
	B(0),

	B(10001),			// 0x4b K
	B(10010),
	B(10100),
	B(11000),
	B(10100),
	B(10010),
	B(10001),
	B(0),

	B(10000),			// 0x4c L
	B(10000),
	B(10000),
	B(10000),
	B(10000),
	B(10000),
	B(11111),
	B(0),

	B(10001),			// 0x4d M
	B(11011),
	B(10101),
	B(10101),
	B(10001),
	B(10001),
	B(10001),
	B(0),

	B(10001),			// 0x4e N
	B(10001),
	B(11001),
	B(10101),
	B(10011),
	B(10001),
	B(10001),
	B(0),

	B(01110),			// 0x4f O
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(11110),			// 0x50 P
	B(10001),
	B(10001),
	B(11110),
	B(10000),
	B(10000),
	B(10000),
	B(0),

	B(01110),			// 0x51 Q
	B(10001),
	B(10001),
	B(10001),
	B(10101),
	B(10010),
	B(01101),
	B(0),

	B(11110),			// 0x52 R
	B(10001),
	B(10001),
	B(11110),
	B(10100),
	B(10010),
	B(10001),
	B(0),

	B(01111),			// 0x53 S
	B(10000),
	B(10000),
	B(01110),
	B(00001),
	B(00001),
	B(11110),
	B(0),

	B(11111),			// 0x54 T
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(10001),			// 0x55 U
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(10001),			// 0x56 V
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(01010),
	B(00100),
	B(0),

	B(10001),			// 0x57 W
	B(10001),
	B(10001),
	B(10001),
	B(10101),
	B(10101),
	B(01010),
	B(0),

	B(10001),			// 0x58 X
	B(10001),
	B(01010),
	B(00100),
	B(01010),
	B(10001),
	B(10001),
	B(0),

	B(10001),			// 0x59 Y
	B(10001),
	B(10001),
	B(01010),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(11111),			// 0x5a Z
	B(00001),
	B(00010),
	B(00100),
	B(01000),
	B(10000),
	B(11111),
	B(0),

	B(01110),			// 0x5b [
	B(01000),
	B(01000),
	B(01000),
	B(01000),
	B(01000),
	B(01110),
	B(0),

	B(10001),			// 0x5c ¥
	B(01010),
	B(11111),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(0),

	B(01110),			// 0x5d ]
	B(00010),
	B(00010),
	B(00010),
	B(00010),
	B(00010),
	B(01110),
	B(0),

	B(00100),			// 0x5e ^
	B(01010),
	B(10001),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0x5f _
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(11111),
	B(0),

	B(01000),			// 0x60 `
	B(00100),
	B(00010),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0x61 a
	B(00000),
	B(01110),
	B(00001),
	B(01111),
	B(10001),
	B(01111),
	B(0),

	B(10000),			// 0x62 b
	B(10000),
	B(10110),
	B(11001),
	B(10001),
	B(10001),
	B(11110),
	B(0),

	B(00000),			// 0x63 c
	B(00000),
	B(01110),
	B(10001),
	B(10000),
	B(10001),
	B(01110),
	B(0),

	B(00001),			// 0x64 d
	B(00001),
	B(01101),
	B(10011),
	B(10001),
	B(10001),
	B(01111),
	B(0),

	B(00000),			// 0x65 e
	B(00000),
	B(01110),
	B(10001),
	B(11111),
	B(10000),
	B(01110),
	B(0),

	B(00011),			// 0x66 f
	B(00100),
	B(01110),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(00000),			// 0x67 g
	B(00000),
	B(01111),
	B(10001),
	B(01111),
	B(00001),
	B(01110),
	B(0),

	B(10000),			// 0x68 h
	B(10000),
	B(10110),
	B(11001),
	B(10001),
	B(10001),
	B(10001),
	B(0),

	B(00100),			// 0x69 i
	B(00000),
	B(01100),
	B(00100),
	B(00100),
	B(00100),
	B(01110),
	B(0),

	B(00010),			// 0x6a j
	B(00000),
	B(00110),
	B(00010),
	B(00010),
	B(10010),
	B(01100),
	B(0),

	B(10000),			// 0x6b k
	B(10000),
	B(10010),
	B(10100),
	B(11000),
	B(10100),
	B(10010),
	B(0),

	B(01100),			// 0x6c l
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(01110),
	B(0),

	B(00000),			// 0x6d m
	B(00000),
	B(11010),
	B(10101),
	B(10101),
	B(10001),
	B(10001),
	B(0),

	B(00000),			// 0x6e n
	B(00000),
	B(10110),
	B(11001),
	B(10001),
	B(10001),
	B(10001),
	B(0),

	B(00000),			// 0x6f o
	B(00000),
	B(01110),
	B(10001),
	B(10001),
	B(10001),
	B(01110),
	B(0),

	B(00000),			// 0x70 p
	B(00000),
	B(11110),
	B(10001),
	B(11110),
	B(10000),
	B(10000),
	B(0),

	B(00000),			// 0x71 q
	B(00000),
	B(01111),
	B(10001),
	B(01111),
	B(00001),
	B(00001),
	B(0),

	B(00000),			// 0x72 r
	B(00000),
	B(10110),
	B(11001),
	B(10000),
	B(10000),
	B(10000),
	B(0),

	B(00000),			// 0x73 s
	B(00000),
	B(01110),
	B(10000),
	B(01110),
	B(00001),
	B(11110),
	B(0),

	B(00000),			// 0x74 t
	B(01000),
	B(11110),
	B(01000),
	B(01000),
	B(01000),
	B(00110),
	B(0),

	B(00000),			// 0x75 u
	B(00000),
	B(10001),
	B(10001),
	B(10001),
	B(10011),
	B(01101),
	B(0),

	B(00000),			// 0x76 v
	B(00000),
	B(10001),
	B(10001),
	B(10001),
	B(01010),
	B(00100),
	B(0),

	B(00000),			// 0x77 w
	B(00000),
	B(10001),
	B(10001),
	B(10101),
	B(10101),
	B(01010),
	B(0),

	B(00000),			// 0x78 x
	B(00000),
	B(10001),
	B(01010),
	B(00100),
	B(01010),
	B(10001),
	B(0),

	B(00000),			// 0x79 y
	B(00000),
	B(10001),
	B(10001),
	B(01111),
	B(00001),
	B(01110),
	B(0),

	B(00000),			// 0x7a z
	B(00000),
	B(11111),
	B(00010),
	B(00100),
	B(01000),
	B(11111),
	B(0),

	B(00010),			// 0x7b {
	B(00100),
	B(00100),
	B(01000),
	B(00100),
	B(00100),
	B(00010),
	B(0),

	B(00100),			// 0x7c |
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(01000),			// 0x7d }
	B(00100),
	B(00100),
	B(00010),
	B(00100),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0x7e →
	B(00100),
	B(00010),
	B(11111),
	B(00010),
	B(00100),
	B(00000),
	B(0),

	B(00000),			// 0x7f ←
	B(00100),
	B(01000),
	B(11111),
	B(01000),
	B(00100),
	B(00000),
	B(0),


	B(00000),			// 0xa0 space
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0xa1 。
	B(00000),
	B(00000),
	B(00000),
	B(11100),
	B(10100),
	B(11100),
	B(0),

	B(00111),			// 0xa2 「
	B(00100),
	B(00100),
	B(00100),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0xa3 」
	B(00000),
	B(00000),
	B(00100),
	B(00100),
	B(00100),
	B(11100),
	B(0),

	B(00000),			// 0xa4 、
	B(00000),
	B(00000),
	B(00000),
	B(10000),
	B(01000),
	B(00100),
	B(0),

	B(00000),			// 0xa5 ・
	B(00000),
	B(00000),
	B(01100),
	B(01100),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0xa6 ヲ
	B(11111),
	B(00001),
	B(01111),
	B(00001),
	B(00010),
	B(01100),
	B(0),

	B(00000),			// 0xa7 ァ
	B(00000),
	B(11111),
	B(00001),
	B(00110),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xa8 ィ
	B(00000),
	B(00010),
	B(00100),
	B(01100),
	B(10100),
	B(00100),
	B(0),

	B(00000),			// 0xa9 ゥ
	B(00000),
	B(00100),
	B(11111),
	B(10001),
	B(00001),
	B(00110),
	B(0),

	B(00000),			// 0xaa ェ
	B(00000),
	B(11111),
	B(00100),
	B(00100),
	B(00100),
	B(11111),
	B(0),

	B(00000),			// 0xab ォ
	B(00000),
	B(00010),
	B(11111),
	B(00110),
	B(01010),
	B(10010),
	B(0),

	B(00000),			// 0xac ャ
	B(00000),
	B(01000),
	B(11111),
	B(01001),
	B(01010),
	B(01000),
	B(0),

	B(00000),			// 0xad ュ
	B(00000),
	B(00000),
	B(11110),
	B(00010),
	B(00010),
	B(11111),
	B(0),

	B(00000),			// 0xae ョ
	B(00000),
	B(11111),
	B(00001),
	B(11111),
	B(00001),
	B(11111),
	B(0),

	B(00000),			// 0xaf ッ
	B(00000),
	B(10101),
	B(10101),
	B(00001),
	B(00001),
	B(00110),
	B(0),

	B(00000),			// 0xb0 ー
	B(00000),
	B(10000),
	B(01111),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(00000),			// 0xb1 ア
	B(11111),
	B(00001),
	B(00101),
	B(00110),
	B(00100),
	B(01000),
	B(0),

	B(00001),			// 0xb2 イ
	B(00010),
	B(00100),
	B(01100),
	B(10100),
	B(00100),
	B(00100),
	B(0),

	B(00100),			// 0xb3 ウ
	B(11111),
	B(10001),
	B(10001),
	B(00001),
	B(00010),
	B(00100),
	B(0),

	B(00000),			// 0xb4 エ
	B(11111),
	B(00100),
	B(00100),
	B(00100),
	B(00100),
	B(11111),
	B(0),

	B(00010),			// 0xb5 オ
	B(11111),
	B(00010),
	B(00110),
	B(01010),
	B(10010),
	B(00010),
	B(0),

	B(01000),			// 0xb6 カ
	B(11111),
	B(01001),
	B(01001),
	B(01001),
	B(01001),
	B(10010),
	B(0),

	B(00100),			// 0xb7 キ
	B(11111),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(00100),
	B(0),

	B(00000),			// 0xb8 ク
	B(01111),
	B(01001),
	B(10001),
	B(00001),
	B(00010),
	B(01100),
	B(0),

	B(01000),			// 0xb9 ケ
	B(01111),
	B(10010),
	B(00010),
	B(00010),
	B(00010),
	B(00100),
	B(0),

	B(00000),			// 0xba コ
	B(11111),
	B(00001),
	B(00001),
	B(00001),
	B(00001),
	B(11111),
	B(0),

	B(01010),			// 0xbb サ
	B(11111),
	B(01010),
	B(01010),
	B(00010),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xbc シ
	B(11001),
	B(00001),
	B(11001),
	B(00001),
	B(00010),
	B(11100),
	B(0),

	B(00000),			// 0xbd ス
	B(11111),
	B(00001),
	B(00010),
	B(00100),
	B(01010),
	B(10001),
	B(0),

	B(01000),			// 0xbe セ
	B(11111),
	B(01001),
	B(01001),
	B(01010),
	B(01000),
	B(00110),
	B(0),

	B(00000),			// 0xbf ソ
	B(10001),
	B(10001),
	B(01001),
	B(00001),
	B(00010),
	B(01100),
	B(0),

	B(00000),			// 0xc0 タ
	B(01111),
	B(01001),
	B(10101),
	B(00011),
	B(00010),
	B(01100),
	B(0),

	B(00010),			// 0xc1 チ
	B(01100),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xc2 ツ
	B(10101),
	B(10101),
	B(10101),
	B(00001),
	B(00010),
	B(00100),
	B(0),

	B(01110),			// 0xc3 テ
	B(00000),
	B(11111),
	B(00100),
	B(00100),
	B(00100),
	B(01000),
	B(0),

	B(01000),			// 0xc4 ト
	B(01000),
	B(01000),
	B(01100),
	B(01010),
	B(01000),
	B(01000),
	B(0),

	B(00100),			// 0xc5 ナ
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xc6 ニ
	B(01110),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(11111),
	B(0),

	B(00000),			// 0xc7 ヌ
	B(11111),
	B(00001),
	B(01010),
	B(00100),
	B(01010),
	B(10001),
	B(0),

	B(00100),			// 0xc8 ネ
	B(11111),
	B(00010),
	B(00100),
	B(01110),
	B(10101),
	B(00100),
	B(0),

	B(00000),			// 0xc9 ノ
	B(00010),
	B(00010),
	B(00010),
	B(00010),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xca ハ
	B(00100),
	B(00010),
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(0),

	B(00000),			// 0xcb ヒ
	B(10000),
	B(11111),
	B(10000),
	B(10000),
	B(10000),
	B(01111),
	B(0),

	B(00000),			// 0xcc フ
	B(11111),
	B(00001),
	B(00001),
	B(00001),
	B(00010),
	B(01100),
	B(0),

	B(00000),			// 0xcd ヘ
	B(01000),
	B(10100),
	B(10010),
	B(00001),
	B(00001),
	B(00000),
	B(0),

	B(00100),			// 0xce ホ
	B(11111),
	B(00100),
	B(10101),
	B(10101),
	B(10101),
	B(00100),
	B(0),

	B(00000),			// 0xcf マ
	B(11111),
	B(00001),
	B(00001),
	B(01010),
	B(00100),
	B(00010),
	B(0),

	B(00000),			// 0xd0 ミ
	B(01110),
	B(00000),
	B(01110),
	B(00000),
	B(01110),
	B(00001),
	B(0),

	B(00000),			// 0xd1 ム
	B(00100),
	B(00100),
	B(01000),
	B(01001),
	B(10011),
	B(11101),
	B(0),

	B(00000),			// 0xd2 メ
	B(00001),
	B(00001),
	B(00101),
	B(00010),
	B(00101),
	B(11000),
	B(0),

	B(00000),			// 0xd3 モ
	B(11111),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(00011),
	B(0),

	B(01000),			// 0xd4 ヤ
	B(01000),
	B(11111),
	B(01001),
	B(01010),
	B(01000),
	B(01000),
	B(0),

	B(00000),			// 0xd5 ユ
	B(01110),
	B(00010),
	B(00010),
	B(00010),
	B(00010),
	B(11111),
	B(0),

	B(00000),			// 0xd6 ヨ
	B(11111),
	B(00001),
	B(01111),
	B(00001),
	B(00001),
	B(11111),
	B(0),

	B(01110),			// 0xd7 ラ
	B(00000),
	B(11111),
	B(00001),
	B(00001),
	B(00010),
	B(00100),
	B(0),

	B(00000),			// 0xd8 リ
	B(10010),
	B(10010),
	B(10010),
	B(00010),
	B(00100),
	B(01000),
	B(0),

	B(00000),			// 0xd9 ル
	B(00100),
	B(10100),
	B(10100),
	B(10101),
	B(10101),
	B(00110),
	B(0),

	B(00000),			// 0xda レ
	B(10000),
	B(10000),
	B(10001),
	B(10010),
	B(10100),
	B(11000),
	B(0),

	B(00000),			// 0xdb ロ
	B(11111),
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(11111),
	B(0),

	B(00000),			// 0xdc ワ
	B(11111),
	B(10001),
	B(10001),
	B(00001),
	B(00010),
	B(00100),
	B(0),

	B(00000),			// 0xdd ン
	B(11000),
	B(00000),
	B(00001),
	B(00001),
	B(00010),
	B(11100),
	B(0),

	B(00100),			// 0xde ゛
	B(10010),
	B(01000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	B(11100),			// 0xdf ゜
	B(10100),
	B(11100),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(0),

	// ここから実際には 5x10 dot も混ざるが、現在はサポートしていない

	B(00000),			// 0xe0 α
	B(00000),
	B(00001),
	B(01101),
	B(10010),
	B(10010),
	B(01101),
	B(00000),

	B(01010),			// 0xe1 a‥(Latin Small Letter A with Diaeresis)
	B(00000),
	B(01110),
	B(00001),
	B(01111),
	B(10001),
	B(01111),
	B(00000),

	B(00000),			// 0xe2 β (10dot)
	B(00000),
	B(01110),
	B(10001),
	B(11110),
	B(10001),
	B(11110),
	B(10000),

	B(00000),			// 0xe3 ε
	B(00000),
	B(01110),
	B(10000),
	B(01110),
	B(10000),
	B(01110),
	B(00000),

	B(00000),			// 0xe4 μ (10dot)
	B(00000),
	B(10001),
	B(10001),
	B(10001),
	B(10011),
	B(11101),
	B(10000),

	B(00000),			// 0xe5 σ
	B(00000),
	B(01111),
	B(10010),
	B(10001),
	B(10001),
	B(01110),
	B(00000),

	B(00000),			// 0xe6 ρ (10dot)
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(00000),			// 0xe7 g (10dot ver)
	B(00000),
	B(01111),
	B(10001),
	B(10001),
	B(10001),
	B(01111),
	B(00001),

	B(00000),			// 0xe8 √(?)
	B(00111),
	B(00100),
	B(00100),
	B(10100),
	B(01000),
	B(00000),
	B(00000),

	B(00000),			// 0xe9 ^(-1) (?)
	B(00010),
	B(11010),
	B(00010),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(00010),			// 0xea j (10dot ver)
	B(00000),
	B(00110),
	B(00010),
	B(00010),
	B(00010),
	B(00010),
	B(00010),

	B(00000),			// 0xeb ^x (?)
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(00000),			// 0xec ¢
	B(00100),
	B(01110),
	B(10100),
	B(10101),
	B(01110),
	B(00100),
	B(00000),

	B(00000),			// 0xed L= (U+26c0 だろうか?)
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(00000),			// 0xee n ̄(n マクロン?)
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(01010),			// 0xef o‥(Latin Small Letter O with Diaeresis)
	B(00000),
	B(01110),
	B(10001),
	B(10001),
	B(10001),
	B(01110),
	B(00000),

	B(00000),			// 0xf0 p (10dot ver)
	B(00000),
	B(10110),
	B(11001),
	B(10001),
	B(10001),
	B(11110),
	B(10000),

	B(00000),			// 0xf1 q (10dot ver)
	B(00000),
	B(01101),
	B(10011),
	B(10001),
	B(10001),
	B(01111),
	B(00001),

	B(01110),			// 0xf2 θ(?)
	B(10001),
	B(10001),
	B(11111),
	B(10001),
	B(10001),
	B(01110),
	B(00000),

	B(00000),			// 0xf3 ∞(?)
	B(00000),
	B(01010),
	B(10101),
	B(10101),
	B(01010),
	B(00000),
	B(00000),

	B(00000),			// 0xf4 Ω
	B(01110),
	B(10001),
	B(10001),
	B(10001),
	B(01010),
	B(11011),
	B(00000),

	B(01010),			// 0xf5 u‥(?)
	B(00000),
	B(10001),
	B(10001),
	B(10001),
	B(10011),
	B(01101),
	B(00000),

	B(11111),			// 0xf6 Σ
	B(01000),
	B(00100),
	B(00010),
	B(00100),
	B(01000),
	B(11111),
	B(00000),

	B(00000),			// 0xf7 π
	B(00000),
	B(11111),
	B(01010),
	B(01010),
	B(01010),
	B(10011),
	B(00000),

	B(11111),			// 0xf8 x ̄(?)
	B(00000),
	B(10001),
	B(01010),
	B(00100),
	B(01010),
	B(10001),
	B(00000),

	B(00000),			// 0xf9 y (10dot ver)
	B(00000),
	B(10001),
	B(10001),
	B(10001),
	B(10001),
	B(01111),
	B(00001),

	B(00000),			// 0xfa 千
	B(00001),
	B(01110),
	B(00100),
	B(11111),
	B(00100),
	B(00100),
	B(00000),

	B(00000),			// 0xfb 万
	B(11111),
	B(01000),
	B(01111),
	B(01001),
	B(01001),
	B(10001),
	B(00000),

	B(00000),			// 0xfc 円
	B(11111),
	B(10101),
	B(10101),
	B(11111),
	B(10001),
	B(10001),
	B(00000),

	B(00000),			// 0xfd ÷
	B(00000),
	B(00100),
	B(00000),
	B(11111),
	B(00000),
	B(00100),
	B(00000),

	B(00000),			// 0xfe space
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),
	B(00000),

	B(11111),			// 0xff cursor
	B(11111),
	B(11111),
	B(11111),
	B(11111),
	B(11111),
	B(11111),
	B(11111),
};

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.