--- nono/vm/vm.cpp 2026/04/29 17:04:28 1.1.1.1 +++ nono/vm/vm.cpp 2026/04/29 17:04:42 1.1.1.5 @@ -1,59 +1,55 @@ // // nono -// Copyright (C) 2017 isaki@NetBSD.org +// Copyright (C) 2020 nono project +// Licensed under nono-license.txt // #include "vm.h" -#include "bitmap.h" -#include "bt454.h" #include "bus.h" -#include "crtc2.h" -#include "ethernet.h" -#include "human68k.h" -#include "lance.h" -#include "lcd.h" -#include "lunakbd.h" -#include "lunarom.h" -#include "mk48t02.h" +#include "mainapp.h" #include "mpu.h" -#include "ppi.h" +#include "mythread.h" #include "ram.h" #include "renderer.h" -#include "rp5c15.h" -#include "scsitarget.h" -#include "sio.h" -#include "spc.h" -#include "sysclk.h" #include "scheduler.h" -#include "x68kkbd.h" -#include "xiospace.h" -#include "zram.h" -VM *gVM; +std::unique_ptr gVM; // コンストラクタ -VM::VM(vmtype_t type) +VM::VM() { - vmtype = type; - // どこでやるのがいいかわからんけど、このコンストラクタはメインスレッドで // 作られるので、ここでメインスレッドの名前を設定。 - pthread_setname_np("Main"); + PTHREAD_SETNAME("Main"); - // Scheduler は必ず先頭。(Scheduler::Init のコメント参照) - gScheduler = new Scheduler(); - buserr = new BusErrDevice(); + // バスエラーデバイスだけここで作成。 + buserr.reset(new BusErrDevice()); // まず全域をバスエラーで初期化。 // この後継承先で必要に応じて上書きする。 for (int i = 0; i < countof(::devtable); i++) { - ::devtable[i] = buserr; + ::devtable[i] = buserr.get(); } } // デストラクタ VM::~VM() { + Dispose(); +} + +// 終了 +void +VM::Dispose() +{ + if ((bool)gScheduler) { + // スケジューラを停止。 + // スケジューラ(VMスレッド)からのアクセスさえなくなれば + // 後の有象無象はグローバルデストラクタにお任せでもいいか。 + // だめだったらもっと頑張る。 + gScheduler->Terminate(); + gScheduler.reset(); + } } // コンストラクタ後の初期化 @@ -109,7 +105,6 @@ VM::DevicePowerOn() ResetHard(); // スケジューラを開始 - // (ResetMPU より後で起動時に1回だけ呼び出す) gScheduler->Run(); return true; @@ -156,292 +151,3 @@ VM::ResetSoft() d->ResetSoft(); } } - - -// -// X68030 VM -// - -// コンストラクタ -VM_X68030::VM_X68030() - : VM(TYPE_X68030) -{ - // デバイス (順序に注意) - // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 - gMPU = new MPUDevice(0xff0000); - gRAM = new RAMDevice(); // required by XIOSpace - xiospace = new XIOSpaceDevice(); - - gKeyboard = new X68030Keyboard(); - gRenderer = new X68030Renderer(); - - // 割り当て - // 今は拡張メモリがないので、今は上位8ビット全領域がミラーになっている。 - for (int i = 0; i < countof(::devtable); i++) { - ::devtable[i] = xiospace; - } -} - -// デストラクタ -VM_X68030::~VM_X68030() -{ -} - -// X68030 の電源ボタンを押します。 -void -VM_X68030::PowerButton() -{ - // 電源 ボタン - // ON OFF->ON 電源オフ割り込みをネゲート? - // ON ON ->OFF 電源オフ割り込みをアサート? - // OFF OFF->ON 電源オン - // OFF ON ->OFF (通常はあり得ないはず) - - // ボタンの状態を更新して.. - power_button = !power_button; - - // デバイスに指示 - DevicePowerOn(); -} - - -// -// LUNA -// - -// コンストラクタ -VM_LUNA::VM_LUNA() - : VM(TYPE_LUNA) -{ - // デバイス (順序に注意) - // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 - gMPU = new MPUDevice(0x41000000); - gRAM = new RAMDevice(); - gPROM = new PROMDevice(); - mk48 = new MK48T02Device(); - gRTC = (RTCDevice *)mk48; // MK48T02 は NVRAM でも RTC でもある… - pio0 = new PIO0Device(); - pio1 = new PIO1Device(); - gSIO = new SIODevice(); - sysclk = new SysClkDevice(); - gZRAM = new ZRAMDevice(); - maskrom = new MaskROMDevice(); - gBitmap = new BitmapDevice(); // required by BT454 - gBT454 = new BT454Device(); - crtc2 = new CRTC2Device(); - gSPC = new SPCDevice(0xe1000000); - gLance = new LanceDevice(); - nulldev = new NullDevice(); - - gEthernet = gLance; - gLCD = new LCDDevice(); - gKeyboard = new LunaKeyboard(); - gRenderer = new LunaRenderer(); - - // デバイスマップから devtable を作成 - for (uint i = 0; i < countof(::devtable); i++) { - IODevice *d; - switch (maptable[i]) { - case NONE: d = nulldev; break; - case BUSERR: d = buserr; break; - case RAM: d = gRAM; break; - case PROM: d = gPROM; break; - case MK48: d = mk48; break; - case PIO0: d = pio0; break; - case PIO1: d = pio1; break; - case SIO: d = gSIO; break; - case TAS: d = gZRAM; break; - case SYSCLK: d = sysclk; break; - case ZRAM: d = gZRAM; break; - case MROM: d = maskrom; break; - case BITMAP: d = gBitmap; break; - case BT454: d = gBT454; break; - case CRTC2: d = crtc2; break; - case SCSI: d = gSPC; break; - case LANCE: d = gLance; break; - default: - __unreachable(); - } - ::devtable[i] = d; - } -} - -// デストラクタ -VM_LUNA::~VM_LUNA() -{ -} - -void -VM_LUNA::PowerButton() -{ - // LUNA の電源ボタンは電源オンにしか使わない。 - // - // 電源 ボタン - // ON PUSH (何も起きない) - // OFF PUSH 電源オン - - // デバイスに指示 - DevicePowerOn(); -} - -// LUNA のデバイス割り当て表 (上位8ビット) -// -// 仕様 実際 -// 00 00 メインメモリ -// -- 01..03 二重バスフォールトするようだ -// -- 04..0f 何かよく分からないものが読める -// -- 10..3f BUSERR -// 41 40..43 PROM -// 45 44..47 mk48t02 -// 49 48..4b pio0 -// 4d 4c..4f pio1 -// 51 50..53 sio -// -- 54..5f 0x7f が読めるようだ -// 61 60..61 TAS -// 63 62..63 システムクロック -// -- 64..6f 61 (TAS) と同じパターンのように見えるけど不詳 -// 71 70..7f 3ポートRAM -// 81 80.. BUSERR (オンボード拡張スロットA) -// 83 ..8f BUSERR (オンボード拡張スロットB) -// 91 90..9f 0xff が読めるようだ (PC-9000 拡張スロット) -// -// a1 マスクROM -// a0,a2,a4,... BUSERR -// a1,a3,a5,... マスクROM -// b1 ビットマップ -// b0/b1 で同様 -// c1 パレット -// c0/c1 で同様 -// d1 CRTC-II -// d0/d1 で同様 -// -// e1 e0..e3 SCSI -// -- e4..ef 不詳だけど、同じパターンが読めるようだ -// f1 f0..f3 LANCE -// -- f4..ff 0xff が読めるようだ - -/*static*/ const uint8 -VM_LUNA::maptable[256] = { - RAM, NONE, NONE, NONE, // 00 (二重バスフォールト領域は未対応) - NONE, NONE, NONE, NONE, // 04 - NONE, NONE, NONE, NONE, // 08 - NONE, NONE, NONE, NONE, // 0c -#if 1 - BUSERR, BUSERR, BUSERR, BUSERR, // 10 - BUSERR, BUSERR, BUSERR, BUSERR, // 14 - BUSERR, BUSERR, BUSERR, BUSERR, // 18 - BUSERR, BUSERR, BUSERR, BUSERR, // 1c - BUSERR, BUSERR, BUSERR, BUSERR, // 20 - BUSERR, BUSERR, BUSERR, BUSERR, // 24 - BUSERR, BUSERR, BUSERR, BUSERR, // 28 - BUSERR, BUSERR, BUSERR, BUSERR, // 2c - BUSERR, BUSERR, BUSERR, BUSERR, // 30 - BUSERR, BUSERR, BUSERR, BUSERR, // 34 - BUSERR, BUSERR, BUSERR, BUSERR, // 38 - BUSERR, BUSERR, BUSERR, BUSERR, // 3c - - PROM, PROM, PROM, PROM, // 40 -#else - // ROM が搭載メモリ量を調べる際の終了条件はここでいう NONE デバイス - // なので、256MB(-32KB) 以上実装する場合は少なくとも実装メモリの直後を - // NONE にしておく必要がある。 - NONE, NONE, NONE, NONE, // 10 - NONE, NONE, NONE, NONE, // 14 - NONE, NONE, NONE, NONE, // 18 - NONE, NONE, NONE, NONE, // 1c - NONE, NONE, NONE, NONE, // 20 - NONE, NONE, NONE, NONE, // 24 - NONE, NONE, NONE, NONE, // 28 - NONE, NONE, NONE, NONE, // 2c - NONE, NONE, NONE, NONE, // 30 - NONE, NONE, NONE, NONE, // 34 - NONE, NONE, NONE, NONE, // 38 - NONE, NONE, NONE, NONE, // 3c - - NONE, PROM, PROM, PROM, // 40 -#endif - MK48, MK48, MK48, MK48, // 44 - PIO0, PIO0, PIO0, PIO0, // 48 - PIO1, PIO1, PIO1, PIO1, // 4c - SIO, SIO, SIO, SIO, // 50 - NONE, NONE, NONE, NONE, // 54 - NONE, NONE, NONE, NONE, // 58 - NONE, NONE, NONE, NONE, // 5c - TAS, TAS, SYSCLK, SYSCLK, // 60 - NONE, NONE, NONE, NONE, // 64 - NONE, NONE, NONE, NONE, // 68 - NONE, NONE, NONE, NONE, // 6c - ZRAM, ZRAM, ZRAM, ZRAM, // 70 - ZRAM, ZRAM, ZRAM, ZRAM, // 74 - ZRAM, ZRAM, ZRAM, ZRAM, // 78 - ZRAM, ZRAM, ZRAM, ZRAM, // 7c - - BUSERR, BUSERR, BUSERR, BUSERR, // 80 - BUSERR, BUSERR, BUSERR, BUSERR, // 84 - BUSERR, BUSERR, BUSERR, BUSERR, // 88 - BUSERR, BUSERR, BUSERR, BUSERR, // 8c - NONE, NONE, NONE, NONE, // 90 - NONE, NONE, NONE, NONE, // 94 - NONE, NONE, NONE, NONE, // 98 - NONE, NONE, NONE, NONE, // 9c - BUSERR, MROM, BUSERR, MROM, // a0 - BUSERR, MROM, BUSERR, MROM, // a4 - BUSERR, MROM, BUSERR, MROM, // a8 - BUSERR, MROM, BUSERR, MROM, // ac - BUSERR, BITMAP, BUSERR, BITMAP, // b0 - BUSERR, BITMAP, BUSERR, BITMAP, // b4 - BUSERR, BITMAP, BUSERR, BITMAP, // b8 - BUSERR, BITMAP, BUSERR, BITMAP, // bc - - BUSERR, BT454, BUSERR, BT454, // c0 - BUSERR, BT454, BUSERR, BT454, // c4 - BUSERR, BT454, BUSERR, BT454, // c8 - BUSERR, BT454, BUSERR, BT454, // cc - BUSERR, CRTC2, BUSERR, CRTC2, // d0 - BUSERR, CRTC2, BUSERR, CRTC2, // d4 - BUSERR, CRTC2, BUSERR, CRTC2, // d8 - BUSERR, CRTC2, BUSERR, CRTC2, // dc - SCSI, SCSI, SCSI, SCSI, // e0 - NONE, NONE, NONE, NONE, // e4 - NONE, NONE, NONE, NONE, // e8 - NONE, NONE, NONE, NONE, // ec - LANCE, LANCE, LANCE, LANCE, // f0 - NONE, NONE, NONE, NONE, // f4 - NONE, NONE, NONE, NONE, // f8 - NONE, NONE, NONE, NONE, // fc -}; - - -// -// RXZ .r .x .z human68k console emulator -// - -// コンストラクタ -VM_RXZ::VM_RXZ(const char *file, const char *arg) - : VM(TYPE_RXZ) -{ - // デバイス (順序に注意) - // Scheduler (と BusErrDevice) は親コンストラクタで作成済み。 - gMPU = new MPUDevice(0); - gRAM = new RAMDevice(); // required by Human68k - gRTC = new RP5C15Device(); - human68k = new Human68k(file, arg); -} - -// デストラクタ -VM_RXZ::~VM_RXZ() -{ -} - -void -VM_RXZ::PowerButton() -{ - // RXZ の電源ボタンは電源オンにしか使わない。 - // - // 電源 ボタン - // ON PUSH (何も起きない) - // OFF PUSH 電源オン - - // デバイスに指示 - DevicePowerOn(); -}