--- nono/vm/lunafb.h 2026/04/29 17:04:55 1.1.1.1 +++ nono/vm/lunafb.h 2026/04/29 17:05:10 1.1.1.2 @@ -4,27 +4,53 @@ // Licensed under nono-license.txt // +// +// LUNA ビットマッププレーン +// + #pragma once -#include "device.h" +#include "planevram.h" #include "monitor.h" -#include -class LunafbDevice : public IODevice +// VRAM の ROP (定数) +struct ROP { + static const uint ZERO = 0; // 0 + static const uint AND1 = 1; // vram & data + static const uint AND2 = 2; // vram & ~data + static const uint cmd = 3; + static const uint AND3 = 4; // ~vram & data + static const uint THRU = 5; // data + static const uint EOR = 6; // vram ^ data + static const uint OR1 = 7; // vram | data + static const uint NOR = 8; // ~vram | ~data + static const uint ENOR = 9; // (vram & data) | (~vram & ~data) + static const uint INV1 = 10; // ~data + static const uint OR2 = 11; // vram | ~data + static const uint INV2 = 12; // ~vram + static const uint OR3 = 13; // ~vram | data + static const uint NAND = 14; // ~vram | ~data + static const uint ONE = 15; // 1 +}; + +class LunafbDevice : public PlaneVRAMDevice { - using inherited = IODevice; + using inherited = PlaneVRAMDevice; static const uint32 plane0base = 0xb10c0000; static const uint32 plane7end = 0xb12c0000; static const uint32 fcset0base = 0xb1300000; static const uint32 fcset7end = 0xb1500000; + + // プレーン数の上限 + static const int MAX_PLANES = 8; + public: LunafbDevice(); virtual ~LunafbDevice() override; bool Init() override; - bool PowerOn() override; - void ResetHard() override; + void ResetHard(bool poweron) override; uint64 Read8(uint32 addr) override; uint64 Read16(uint32 addr) override; @@ -34,89 +60,66 @@ class LunafbDevice : public IODevice uint64 Write32(uint32 addr, uint32 data) override; uint64 Peek8(uint32 addr) override; - // プレーン数を取得 - int GetPlaneCount() const { return nplane; } - - // RFCNT によるオフセットを取得 (レンダラ用) - void GetRFCNT(int *h, int *v) const { - *h = hscroll; - *v = vscroll; - } - - // ビットマップのアドレスを取得 - const uint8 *GetBuf() const { return mem.get(); } - - // 更新フラグのアドレスを取得 - std::atomic *GetDirty() { return atomic_dirty; } - // エミュレータによる出力 - void EmuConsoleOpen(TextScreen *t); - void EmuConsoleUpdate(); - void EmuConsoleClose(); + void EmuInitScreen(); + void EmuFill(uint x, uint y, uint w, uint h, uint32 data); + void EmuPutc(uint x, uint y, uint c); + void EmuPutc(uint x, uint y, uint c, int rop); + void EmuScrollY(uint dy, uint sy, uint h); private: - void Invalidate(); + // offset の VRAM が変更されたことを記録する + inline void SetDirty(uint32 offset); + void WriteRFCNT(uint32); void WriteCommonBitmap8(uint32, uint32); void WriteCommonBitmap16(uint32, uint32); void WriteCommonBitmap32(uint32, uint32); + void WriteCommonFCSet(uint rop, uint32 data); void WritePlane8(uint, uint32, uint32); void WritePlane16(uint, uint32, uint32); void WritePlane32(uint, uint32, uint32); DECLARE_MONITOR_CALLBACK(MonitorUpdate); + // 演算 + static uint32 RasterOp(uint rop, uint32 vram, uint32 data); + // ROP 文字列を返す static const char *RopStr(uint rop); - // プレーン数の上限 - static const int MAX_PLANES = 8; - - // プレーン数 (設定による) - int nplane {}; - // 現在のプレーン数でのプレーンの終了アドレス uint32 plane_end {}; // RFCNT - // b31..b24 b23..b16 b15..b10 b09..b00 - // 無効 水平カウンタ 無効 ラスタカウンタ + // + // 3 2 1 0 + // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + // +---------------+---------------+-----------+---+---------------+ + // | 無効 | 水平カウンタ | 無効 | ラスタカウンタ | + // +---------------+---------------+-----------+---+---------------+ uint32 rfcnt {}; - int hscroll {}; - int vscroll {}; + // 親クラスにある + // int xscroll {}; + // int yscroll {}; // プレーンセレクタ - // b31...b4 b3 b2 b1 b0 - // <-無効-> | | | +-- プレーン0 (%1=同時設定/書き込み有効、%0=無効) - // | | +----- プレーン1 - // | +-------- プレーン2 - // +----------- プレーン3 - uint32 bmsel {}; + // + // 3 2 1 0 + // 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 + // +---------------+---------------+---------------+-------+-+-+-+-+ + // | 無効 |3|2|1|0| + // +---------------+---------------+---------------+-------+-+-+-+-+ + // | | | | + // プレーンN (%1 = 同時設定/書き込み有効、%0=無効) --------+-+-+-+ - // ビットマッププレーン。 - // ロングワードでホストバイトオーダー。 - // 1枚が 256KB。1 or 4枚 - std::unique_ptr mem {}; - - // 更新フラグ。 - // 更新があったラインは 1、なければ 0。 - // 1ラインごとなので 1プレーンにつき 1024 エントリ。 - // XXX 水平の非描画区間は今の所検出していないので描画側で多少無駄足。 - std::atomic atomic_dirty[1024] {}; + uint32 bmsel {}; // ファンクションセットとアクセスマスク - u_int fcs[MAX_PLANES] {}; - uint32 mask[MAX_PLANES] {}; + uint fcset[MAX_PLANES] {}; + uint32 fcmask[MAX_PLANES] {}; Monitor monitor { this }; - - // エミュレータによるコンソール出力 - TextScreen *textscr {}; - std::vector prev {}; - int screen_w {}; // 桁数 - int screen_h {}; // 行数 - int origin_x {}; // 原点 X [dot] - int origin_y {}; // 原点 Y [dot] }; -extern std::unique_ptr gLunafb; +#define gLunafb (dynamic_cast(gPlaneVRAM))