--- nono/vm/lcd.h 2026/04/29 17:04:39 1.1.1.4 +++ nono/vm/lcd.h 2026/04/29 17:05:18 1.1.1.10 @@ -4,32 +4,37 @@ // Licensed under nono-license.txt // +// +// LCD (HD44780) +// + #pragma once #include "device.h" +#include "monitor.h" class LCDDevice : public Device { using inherited = Device; public: LCDDevice(); - ~LCDDevice() override; + virtual ~LCDDevice() override; - bool PowerOff() override; - void MonitorUpdate(TextScreen&) override; + void ResetHard(bool poweron) override; + void PowerOff() override; // リセット信号はない - // R/~W を val にセットする。%1=R、%0=W + // R/~W を val にセットする。true=R、false=W void SetRW(bool val); // RS を val にセットする。 - // %0=コマンド(W)/ステータス(R)レジスタ - // %1=データレジスタ - void SetRS(int); + // false=コマンド(W)/ステータス(R)レジスタ + // true=データレジスタ + void SetRS(bool val); // E を val にセットする。 - void SetE(bool); + void SetE(bool val); // E, RS, R/W 線の状態を取得する。 // PIO1 のポートC 読み込み用。 @@ -50,39 +55,39 @@ class LCDDevice : public Device // フォントを取得 const uint8 *GetFont(int ch) const; - // 更新カウンタ取得 - uint32 GetCounter() const { return update; } - private: - bool en = false; // Enable - bool rw = false; // R/~W - int rs = 0; // レジスタセレクト - - bool addr_inc = false; // アドレス・インクリメント - bool disp_char = false; // 文字表示をするか - int addr = 0; // アドレスカウンタ - - // CGRAM と DDRAM はコマンドでのアドレス指定と同じ位置にマップさせておく。 - // そのため先頭の 64(0x40)バイトは使わず肥やしにする。 - union { - struct { - uint8 unused[0x40]; - uint8 cgram[0x40]; - uint8 ddram[0x80]; - }; - uint8 ram[256] {}; - }; - - // RAM 更新カウンタ。 - // CGRAM や DDRAM など表示内容が変化するごとに 1 ずつ上がるカウンタ。 - // GUI 側にて前回描画時のカウンタと比較して異なっていれば前回から - // 何かしらの更新があったものとして再描画する。どこがどう変化したかの - // 情報は持っていない。 - // XXX もうちょっといい方法 - // XXX 電源オフどうするか - uint32 update = 0; + DECLARE_MONITOR_CALLBACK(MonitorUpdate); + + // 現在のアドレスでデータレジスタにラッチ + void LatchData(); + // アドレスカウンタ設定 + void SetAddr(int addr, bool is_cgram); + // アドレスカウンタを次へ進める + void NextAddr(); + + // 信号線 + bool en {}; // Enable + bool rw {}; // true=R false=W + bool rs {}; // レジスタセレクト true=Data false=Command/Status + + bool addr_inc {}; // アドレス・インクリメント true=inc false=dec + bool disp_char {}; // 文字表示をするか + + // データレジスタ + uint8 data_reg {}; + + // アドレスカウンタ + int addr_counter {}; + bool addr_is_cgram {}; // addr が CGRAM アドレスなら true + + uint8 ddram[0x80] {}; + uint8 cgram[0x40] {}; + + Monitor monitor { this }; static const uint8 CGROM[12 * 16 * 8]; }; -extern std::unique_ptr gLCD; +static inline LCDDevice *GetLCDDevice() { + return Object::GetObject(OBJ_LCD); +}