--- nono/vm/lcd.h 2026/04/29 17:04:28 1.1 +++ nono/vm/lcd.h 2026/04/29 17:04:39 1.1.1.4 @@ -1,6 +1,7 @@ // // nono -// Copyright (C) 2018 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #pragma once @@ -9,37 +10,48 @@ class LCDDevice : public Device { - typedef Device inherited; + using inherited = Device; public: LCDDevice(); - virtual ~LCDDevice(); + ~LCDDevice() override; - virtual bool PowerOff(); + bool PowerOff() override; + void MonitorUpdate(TextScreen&) override; // リセット信号はない - // R/~W を val にセットします。%1=R、%0=W です。 + // R/~W を val にセットする。%1=R、%0=W void SetRW(bool val); - // RS を val にセットします。 + // RS を val にセットする。 // %0=コマンド(W)/ステータス(R)レジスタ // %1=データレジスタ void SetRS(int); - // E を val にセットします。 + // E を val にセットする。 void SetE(bool); // E, RS, R/W 線の状態を取得する。 // PIO1 のポートC 読み込み用。 uint8 Get() const; - // 読み込みます。 + // 読み込む。 uint8 Read(); - // 書き込みます。 + // 書き込む。 void Write(uint8 data); - virtual bool MonitorUpdate(); + // PIO1 のポートA ピーク用 + uint8 Peek() const; + + // バッファを取得 (内容表示用) + const uint8 *GetDDRAM() const { return ddram; } + + // フォントを取得 + const uint8 *GetFont(int ch) const; + + // 更新カウンタ取得 + uint32 GetCounter() const { return update; } private: bool en = false; // Enable @@ -49,7 +61,28 @@ class LCDDevice : public Device bool addr_inc = false; // アドレス・インクリメント bool disp_char = false; // 文字表示をするか int addr = 0; // アドレスカウンタ - uint8 ddram[0x40 * 2] {}; + + // 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; + + static const uint8 CGROM[12 * 16 * 8]; }; -extern LCDDevice *gLCD; +extern std::unique_ptr gLCD;