--- nono/vm/romemu_luna.h 2026/04/29 17:04:39 1.1.1.3 +++ nono/vm/romemu_luna.h 2026/04/29 17:06:00 1.1.1.17 @@ -4,98 +4,172 @@ // Licensed under nono-license.txt // +// +// LUNA シリーズの ROM エミュレーション共通部分 +// + #pragma once -#include "device.h" +#include "romemu.h" +#include "fixedqueue.h" -class LunaPROMEmuDevice : public IODevice +class BT45xDevice; +class LanceDevice; +class LunafbDevice; +class MainRAMDevice; +class MK48T02Device; +class SIODevice; +class SPCDevice; + +class LunaPROMEmuDevice : public ROMEmuDevice { - using inherited = IODevice; + using inherited = ROMEmuDevice; + protected: // このデバイス先頭アドレス static const uint32 baseaddr = 0x41000000; // 謎の I/O 空間 static const uint32 ROMIO_BASE = 0x41010000; - static const uint32 ROMIO_INIT = (ROMIO_BASE + 0); - static const uint32 ROMIO_KEYIN = (ROMIO_BASE + 4); - static const uint32 ROMIO_CLOSE = (ROMIO_BASE + 8); + static const uint32 ROMIO_INIT = (ROMIO_BASE + 0x00); + static const uint32 ROMIO_LOAD = (ROMIO_BASE + 0x04); + static const uint32 ROMIO_SIOINTR = (ROMIO_BASE + 0x08); + static const uint32 ROMIO_CLOSE = (ROMIO_BASE + 0x0c); + static const uint32 ROMIO_ENTRY = (ROMIO_BASE + 0x10); + static const uint32 ROMIO_AP1 = (ROMIO_BASE + 0x14); + static const uint32 ROMIO_AP2 = (ROMIO_BASE + 0x18); + static const uint32 ROMIO_CLKCNT = (ROMIO_BASE + 0x1c); + static const uint32 ROMIO_QUITSTOP = (ROMIO_BASE + 0x20); + + // 文字コード + // 概ね ASCII だが制御コード部分は必要な文字だけを適当に割り当てる。 + static const char BS = 0x08; + static const char LF = 0x0a; + static const char CR = 0x0d; + static const char UP = 0x1c; + static const char LEFT = 0x1d; + static const char RIGHT = 0x1e; + static const char DOWN = 0x1f; + + // ブート情報格納用 + struct bootinfo_t { + int dkunit {}; + int dkpart {}; + std::string dkfile {}; + }; public: LunaPROMEmuDevice(); ~LunaPROMEmuDevice() override; bool Init() override; - void ResetHard() override; - uint64 Read8(uint32 addr) override; - uint64 Read16(uint32 addr) override; - uint64 Read32(uint32 addr) override; - uint64 Write8(uint32 addr, uint32 data) override; - uint64 Write16(uint32 addr, uint32 data) override; - uint64 Write32(uint32 addr, uint32 data) override; - uint64 Peek8(uint32 addr) override; + protected: + uint64 ReadROMIO(busaddr addr) override; + bool WriteROMIO(busaddr addr, uint32 data) override; + + void ROM_Init(); + virtual void ROM_InitMD() = 0; + uint32 ROM_Load(); + uint32 ROM_Entry(); + virtual void ROM_Close(); + void ROM_AP1(); + void ROM_AP2(); + virtual uint32 LoadFile(const std::string& fname) = 0; + virtual void ProcessChar(char); + virtual void Command() = 0; + + void InitScreen(); + void InitPalette(); + void PrintTitle(); + void ClearPrompt(); + int Getc(); + void Putc(uint ch); + void Print(const std::string& s); + void Print(const char *fmt, ...) __printflike(2, 3); + void PrintDisplay(const char *s); - private: - uint64 Decoder(uint32 addr) const; + // NVRAM + virtual bool InitNVRAM() = 0; + virtual void GetNVRAM(bootinfo_t&) = 0; + uint8 CalcNVRAMCsum() const; + void WriteNVRAMCsum(); + bool VerifyNVRAM() const; - uint32 ROM_Init(); - uint32 ROM_Close(); - uint32 ROM_Keyin(); - void ConsoleUpdate(); - uint32 Command(); - void CommandG(const std::vector& arg); - void CommandGH(); uint32 LoadHostFile(); - void CommandK(const std::vector& arg); - bool CommandKInput(const std::string& val); - uint32 CommandX(); - - std::unique_ptr romdata; + uint32 LoadGuestFile(const bootinfo_t&); - // NVRAM - uint8 CalcNVRAMCsum(); - void WriteNVRAMCsum(); - bool VerifyNVRAM(); - bool InitNVRAM(); + // 読み込んだプログラムのエントリポイント。 + // エントリポイントがセットされていない時は -1。 + uint32 entrypoint {}; + + // エントリポイントに実行を移す時には true。 + // LUNA-I は 'x' コマンドを実行したら。 + // LUNA-88K では 'b'/'bh' コマンドで。 + bool execute {}; - // NVRAM の設定に従って起動 - uint32 LoadByNVRAM(const std::string& fname); + // シリアルか。(DIP-SW で決まる) + bool use_serial {}; - // 内蔵 ROM 使用後はアクセスできないようにするため - bool is_closed = false; + // 機種名 (タイトル表示用) + const char *machine_name {}; - // 'g' コマンドで読み込んだプログラムのエントリポイント。 - // なければ 0。'x' コマンドで使う。 - uint32 entrypoint; // エラーメッセージの受け渡し用 // 基本的にエラーが起きた時だけ更新するので、ここにエラーメッセージを // 返す可能性がある関数をコールする前に呼び出し側が clear() しておき、 // 関数から戻ったら empty() かどうか確認する、errno みたいな使い方。 - std::string errmsg; - - // ROM モニタ用コンソール画面 - TextConsole text; + std::string errmsg {}; // 入力バッファ std::string inputbuf {}; - int inputpos {}; // カーソル位置 - bool is_shift; // SHIFT キー押し下げ中 + + // 現在のプロンプト文字列 + std::string prompt {}; + + // デフォルトプロンプト。 + const std::string default_prompt = ">"; + + // プロンプトのある行(最上行が 0) + int prompt_y {}; + + // カーソル位置(入力バッファ先頭が0) + int inputpos {}; + + int screen_w {}; // テキスト桁数 + int screen_h {}; // テキスト行数 + int cursor_x {}; // カーソル位置(桁) + int cursor_y {}; // カーソル位置(行) + bool cursor_on {}; // カーソル表示 + bool bold {}; + int origin_px {}; // テキスト画面の左上 X 座標(ピクセル) + int origin_py {}; // テキスト画面の左上 Y 座標(ピクセル) + + BT45xDevice *bt45x {}; + LanceDevice *lance {}; + LunafbDevice *lunafb {}; + MainRAMDevice *mainram {}; + MK48T02Device *nvram {}; + SIODevice *sio {}; + SPCDevice *spc {}; + + private: + void ROM_SIOIntr(); + void PutcSerial(uint); + void PutcDisplay(uint); + void ProcessSerial(); + int GetcSerial(); + int GetcKeyboard(); + + bool is_shift {}; // SHIFT キー押し下げ中 int mousecnt {}; // マウス入力をスキップするためのカウンタ - // プロンプトと入力モード - std::string prompt {}; // 現在のプロンプト文字列 - // プロンプトの状態。 - // 0 が通常プロンプト。 - // 1 以降は k コマンドのプロンプトを示す - int prompt_idx {}; - const std::string default_prompt = ">"; // デフォルトプロンプト + FixedQueue sio_txq; // シリアル送信キュー - // NVRAM - // 本来他デバイスはすべてグローバル参照できるのだが、LUNA の NVRAM は - // RTC と兼用になっていて、RTCDevice *gRTC として見えるので - // MK48T02Device にするには dynamic_cast する必要がある。 - MK48T02Device *nvram; + uint32 clkcnt {}; // クロック割り込みカウンタ + + // luna88k で割り込みからジャンプして戻る時のアドレス。 + // 0 なら作用しない。 + uint32 quitstop {}; // LUNA キーコード -> ASCII 変換テーブル static const uint8 lunakey2asciitable[128];