Annotation of nono/vm/vm.cpp, revision 1.1.1.8

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.8 ! root        7: //
        !             8: // VM (基本クラス)
        !             9: //
        !            10: 
1.1       root       11: #include "vm.h"
1.1.1.8 ! root       12: #include "debugger_private.h"
1.1.1.3   root       13: #include "mainapp.h"
1.1       root       14: #include "mpu.h"
1.1.1.8 ! root       15: #include "power.h"
1.1       root       16: #include "ram.h"
                     17: #include "scheduler.h"
1.1.1.8 ! root       18: #include "signalthread.h"
        !            19: #include "sync.h"
1.1       root       20: 
1.1.1.8 ! root       21: // グローバル参照用
        !            22: VM *gVM;
1.1       root       23: 
                     24: // コンストラクタ
1.1.1.3   root       25: VM::VM()
1.1       root       26: {
1.1.1.8 ! root       27:        // SignalThread は他のスレッドより先に起動する必要があるので、先頭。
        !            28:        // Scheduler は以降の他のデバイスからのイベント登録を受け付ける必要が
        !            29:        // あるためその次。
        !            30:        NEWDV(SignalThread, new SignalThread());
        !            31:        NEWDV(Scheduler, new Scheduler());
        !            32:        NEWDV(Sync, new Sync());
        !            33:        NEWDV(Power, new PowerDevice());
        !            34:        NEWDV(Debugger, new Debugger());
1.1       root       35: 
1.1.1.8 ! root       36:        // バスエラーデバイスをここで作成して全域をバスエラーで初期化。
1.1       root       37:        // この後継承先で必要に応じて上書きする。
1.1.1.8 ! root       38:        NEWDV(BusErr, new BusErrDevice());
1.1       root       39:        for (int i = 0; i < countof(::devtable); i++) {
1.1.1.8 ! root       40:                ::devtable[i] = gBusErr;
1.1       root       41:        }
                     42: }
                     43: 
                     44: // デストラクタ
                     45: VM::~VM()
                     46: {
1.1.1.4   root       47:        Dispose();
1.1.1.8 ! root       48:        gVM = NULL;
1.1.1.4   root       49: }
                     50: 
                     51: // 終了
                     52: void
                     53: VM::Dispose()
                     54: {
1.1.1.8 ! root       55:        // まずスレッドを止める。
        !            56:        // デバッガスレッドがスケジューラスレッドにアクセスするのでデバッガが先。
        !            57:        if ((bool)pDebugger) {
        !            58:                gDebugger->TerminateThread();
        !            59:        }
        !            60:        if ((bool)pScheduler) {
        !            61:                gScheduler->TerminateThread();
        !            62:        }
        !            63: 
        !            64:        // 残りのスレッドを停止
        !            65:        for (auto obj : gMainApp.GetObjects()) {
        !            66:                auto th = dynamic_cast<ThreadDevice *>(obj);
        !            67:                if (th) {
        !            68:                        th->TerminateThread();
        !            69:                }
1.1.1.4   root       70:        }
1.1.1.8 ! root       71: 
        !            72:        // 作ったときと逆順で解放する
        !            73:        if ((bool)pDebugger) {
        !            74:                pDebugger.reset();
        !            75:        }
        !            76: 
        !            77:        if ((bool)pScheduler) {
        !            78:                pScheduler.reset();
        !            79:        }
        !            80: 
        !            81:        // ほかのオブジェクトの解放はグローバルデストラクタにおまかせ。
        !            82:        // だめだったらまた考える。
1.1       root       83: }
                     84: 
                     85: // コンストラクタ後の初期化
                     86: bool
                     87: VM::Create()
                     88: {
1.1.1.8 ! root       89:        // d->Create() は Object を追加する場合があるため、ここで
1.1.1.7   root       90:        // ranged for は使えない。また追加されたデバイスの Create() も(念のため)
                     91:        // 実行したいため、ループ終了条件で毎回 size() を取り出して比較する。
1.1.1.8 ! root       92:        for (int i = 0; i < gMainApp.GetObjects().size(); i++) {
        !            93:                auto dev = dynamic_cast<Device *>(gMainApp.GetObjects()[i]);
        !            94:                if (dev) {
        !            95:                        if (!dev->Create()) {
        !            96:                                return false;
        !            97:                        }
1.1       root       98:                }
                     99:        }
                    100: 
                    101:        return true;
                    102: }
                    103: 
                    104: // 初期化
                    105: bool
                    106: VM::Init()
                    107: {
1.1.1.8 ! root      108:        for (auto obj : gMainApp.GetObjects()) {
        !           109:                auto dev = dynamic_cast<Device *>(obj);
        !           110:                if (dev) {
        !           111:                        if (!dev->Init()) {
        !           112:                                return false;
        !           113:                        }
        !           114:                }
        !           115:        }
        !           116: 
        !           117:        return true;
        !           118: }
        !           119: 
        !           120: // スレッド開始
        !           121: bool
        !           122: VM::StartThread()
        !           123: {
        !           124:        for (auto obj : gMainApp.GetObjects()) {
        !           125:                auto th = dynamic_cast<ThreadDevice *>(obj);
        !           126:                if (th) {
        !           127:                        if (!th->StartThread()) {
        !           128:                                return false;
        !           129:                        }
1.1       root      130:                }
                    131:        }
                    132: 
                    133:        return true;
                    134: }
                    135: 
                    136: // 設定の適用
                    137: bool
                    138: VM::Apply()
                    139: {
1.1.1.8 ! root      140:        for (auto obj : gMainApp.GetObjects()) {
        !           141:                auto dev = dynamic_cast<Device *>(obj);
        !           142:                if (dev) {
        !           143:                        if (!dev->Apply()) {
        !           144:                                return false;
        !           145:                        }
1.1       root      146:                }
                    147:        }
                    148: 
                    149:        return true;
                    150: }
                    151: 
1.1.1.7   root      152: // ブートページを切り替える (共通処理)
                    153: // 派生クラスから呼ぶこと。
1.1       root      154: void
1.1.1.7   root      155: VM::SwitchBootPage(Device *parent, bool isrom)
1.1       root      156: {
1.1.1.7   root      157:        // ログ表示
                    158:        if (isrom) {
                    159:                parent->putlogf(1, lstr("SwitchBootPage ROM (Boot)"));
                    160:        } else {
                    161:                parent->putlogf(1, lstr("SwitchBootPage RAM (Normal)"));
1.1       root      162:        }
1.1.1.7   root      163: 
1.1.1.8 ! root      164:        // 同期モード指示
        !           165:        gSync->RequestBootPageMode(isrom);
        !           166: }
        !           167: 
        !           168: // MPU の RESET 命令によるリセット
        !           169: void
        !           170: VM::ResetByMPU()
        !           171: {
1.1       root      172: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.