--- nono/vm/romemu_luna88k.cpp 2026/04/29 17:04:50 1.1.1.5 +++ nono/vm/romemu_luna88k.cpp 2026/04/29 17:04:53 1.1.1.6 @@ -57,12 +57,19 @@ Luna88kPROMEmuDevice::Init() MemoryStreamBE ms(romdata.get()); - // MPU を仕様通りに動作させるなら、リセット時に ROM を 0番地付近に見せて - // 実行中に RAM に切り替えるのが定番だが、nono ではそれは意図して実装して - // いない。従って xip = $41000000 から実行開始するのに対して vbr の初期値 - // は 0 なので、ROM の $41000008 以降をベクタ用にリザーブする必要がない。 - // よって $41000000 から直接コードを置いていく。 + // リセット時のブートページには ROM (これ) が見えている。 + // ROMIO_INIT へのアクセスでブートページを RAM に切り替えて、同時に RAM の + // 0番地付近のベクタも作り直す。そのため、ここのベクタ1 以降 ($41000008〜) + // をベクタとして参照することはないので、ベクタ0 の命令列がそのまま使い潰 + // してよい。というか2ワードでは 0番地から ROM まで飛べないので使わないと + // 面倒くさい。一体どういう設計してんだ…。 + + // ; _ROM_START へジャンプ (ここは0番地) + ms.Write32(0x5cc04100); // or.u r6, r0, #0x4100 + ms.Write32(0x58c6000c); // or r6, r6, #0x000c + ms.Write32(0xf400c006); // jmp r6 + // _ROM_START: (ここは ROM) // ; 元の PSR を r10 に保存しつつ // ; 割り込み許可 ms.Write32(0x81404020); // ldcr r10, psr @@ -108,6 +115,14 @@ Luna88kPROMEmuDevice::Init() return true; } +void +Luna88kPROMEmuDevice::ResetHard() +{ + inherited::ResetHard(); + + b_entrypoint = 0; +} + // 起動時の処理を行う。 // 次段実行ファイルの読み込みに成功すればそのエントリポイントを返す。 // そうでなければ 0 を返すので、プロンプトに処理を移すこと。 @@ -119,6 +134,7 @@ Luna88kPROMEmuDevice::ROM_Init() // デバイスの初期化 (親クラス) InitDevice(); + // 割り込みマスクで SIO だけ許可 gInterrupt->Write32(0x65000000, 0x40000000); @@ -238,19 +254,11 @@ Luna88kPROMEmuDevice::Command() // 1ワードごとに分解 strcpy(&buf[0], inputbuf.c_str()); char *p = &buf[0]; - char *s = p; - while (*p != '\0') { - if (*p == ' ') { - *p++ = '\0'; - arg.push_back(std::string(s)); - s = p; - } else { - p++; + for (char *ap; (ap = strsep(&p, " ")) != NULL; ) { + if (*ap != '\0') { + arg.push_back(std::string(ap)); } } - if (p != s) { - arg.push_back(std::string(s)); - } if (loglevel >= 1) { for (int i = 0; i < arg.size(); i++) { putmsgn("arg[%d]=|%s|", i, arg[i].c_str());