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

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

unix.superglobalmegacorp.com

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