|
|
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:
22: // コンストラクタ
1.1.1.11! root 23: VM::VM(const char *vmname_)
1.1 root 24: {
1.1.1.11! root 25: vmname = vmname_;
! 26: assert(vmname);
! 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(Debugger, new Debugger());
1.1 root 35: }
36:
37: // デストラクタ
38: VM::~VM()
39: {
1.1.1.4 root 40: Dispose();
41: }
42:
43: // 終了
44: void
45: VM::Dispose()
46: {
1.1.1.8 root 47: // まずスレッドを止める。
48: // デバッガスレッドがスケジューラスレッドにアクセスするのでデバッガが先。
49: if ((bool)pDebugger) {
1.1.1.9 root 50: GetDebugger()->TerminateThread();
1.1.1.8 root 51: }
52: if ((bool)pScheduler) {
1.1.1.9 root 53: GetScheduler()->TerminateThread();
1.1.1.8 root 54: }
55:
56: // 残りのスレッドを停止
57: for (auto obj : gMainApp.GetObjects()) {
58: auto th = dynamic_cast<ThreadDevice *>(obj);
59: if (th) {
60: th->TerminateThread();
61: }
1.1.1.4 root 62: }
1.1.1.8 root 63:
64: // 作ったときと逆順で解放する
65: if ((bool)pDebugger) {
66: pDebugger.reset();
67: }
68:
69: if ((bool)pScheduler) {
70: pScheduler.reset();
71: }
72:
73: // ほかのオブジェクトの解放はグローバルデストラクタにおまかせ。
74: // だめだったらまた考える。
1.1 root 75: }
76:
77: // コンストラクタ後の初期化
78: bool
79: VM::Create()
80: {
1.1.1.8 root 81: // d->Create() は Object を追加する場合があるため、ここで
1.1.1.10 root 82: // ranged for は使えない。また追加されたデバイスの Create() も
1.1.1.7 root 83: // 実行したいため、ループ終了条件で毎回 size() を取り出して比較する。
1.1.1.8 root 84: for (int i = 0; i < gMainApp.GetObjects().size(); i++) {
85: auto dev = dynamic_cast<Device *>(gMainApp.GetObjects()[i]);
86: if (dev) {
87: if (!dev->Create()) {
88: return false;
89: }
1.1 root 90: }
91: }
92:
93: return true;
94: }
95:
96: // 初期化
97: bool
98: VM::Init()
99: {
1.1.1.8 root 100: for (auto obj : gMainApp.GetObjects()) {
101: auto dev = dynamic_cast<Device *>(obj);
102: if (dev) {
103: if (!dev->Init()) {
104: return false;
105: }
106: }
107: }
108:
1.1.1.11! root 109: // デバイスの初期化が全部出来たのでメインバスの初期化。
! 110: auto mainbus = dynamic_cast<MainbusDevice*>(pMainbus.get());
! 111: if (mainbus->InitMainbus() == false) {
! 112: return false;
! 113: }
! 114:
1.1.1.8 root 115: return true;
116: }
117:
118: // スレッド開始
119: bool
120: VM::StartThread()
121: {
122: for (auto obj : gMainApp.GetObjects()) {
123: auto th = dynamic_cast<ThreadDevice *>(obj);
124: if (th) {
125: if (!th->StartThread()) {
126: return false;
127: }
1.1 root 128: }
129: }
130:
131: return true;
132: }
133:
134: // 設定の適用
135: bool
136: VM::Apply()
137: {
1.1.1.8 root 138: for (auto obj : gMainApp.GetObjects()) {
139: auto dev = dynamic_cast<Device *>(obj);
140: if (dev) {
141: if (!dev->Apply()) {
142: return false;
143: }
1.1 root 144: }
145: }
146:
147: return true;
148: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.