|
|
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.12 root 7: //
8: // デバイスの基本クラスなど
9: //
10:
1.1 root 11: #pragma once
12:
13: #include "object.h"
1.1.1.15 root 14: #include "bus.h"
1.1 root 15:
16: #if BYTE_ORDER == LITTLE_ENDIAN
17: #define HB(addr) ((addr) ^ 1)
18: #define HLB(addr) ((addr) ^ 3)
19: #define HLW(addr) ((addr) ^ 2)
20: #else
21: #define HB(addr) (addr)
1.1.1.5 root 22: #define HLB(addr) (addr)
23: #define HLW(addr) (addr)
1.1 root 24: #endif
25:
1.1.1.15 root 26: // デバイスを作成して代入するマクロ。
27: // …だったが今となってはあまり意味がなくなっている。
28: #define NEWDV(NAME, NEW_CTOR) do { \
29: __CONCAT(p,NAME).reset(NEW_CTOR); \
1.1.1.16 root 30: assert((bool)__CONCAT(p,NAME)); \
1.1.1.15 root 31: } while (0)
32:
1.1.1.18! root 33: // ユーザ定義リテラルを使ったサフィックス
! 34:
! 35: // ナノ秒
! 36: static inline constexpr uint64 operator"" _nsec(unsigned long long ns)
! 37: {
! 38: return ns;
! 39: }
! 40: static inline constexpr uint64 operator"" _nsec(long double ns)
! 41: {
! 42: return ns;
! 43: }
! 44:
! 45: // マイクロ秒
! 46: static inline constexpr uint64 operator"" _usec(unsigned long long us)
! 47: {
! 48: return us * 1000_nsec;
! 49: }
! 50: static inline constexpr uint64 operator"" _usec(long double us)
! 51: {
! 52: return us * 1000_nsec;
! 53: }
! 54:
! 55: // ミリ秒
! 56: static inline constexpr uint64 operator"" _msec(unsigned long long ms)
! 57: {
! 58: return ms * 1000_usec;
! 59: }
! 60: static inline constexpr uint64 operator"" _msec(long double ms)
! 61: {
! 62: return ms * 1000_usec;
! 63: }
! 64:
! 65: // 秒
! 66: static inline constexpr uint64 operator"" _sec(unsigned long long sec)
! 67: {
! 68: return sec * 1000_msec;
! 69: }
! 70: static inline constexpr uint64 operator"" _sec(long double sec)
! 71: {
! 72: return sec * 1000_msec;
! 73: }
! 74:
1.1.1.13 root 75: // 前方参照
1.1.1.18! root 76: class Device;
! 77: class Event;
1.1.1.16 root 78: class MainMPUDevice;
1.1.1.13 root 79: class Scheduler;
80:
1.1.1.18! root 81: using EventCallback_t = void (Device::*)(Event *);
! 82:
1.1 root 83: class Device : public Object
84: {
1.1.1.4 root 85: using inherited = Object;
1.1 root 86: protected:
1.1.1.16 root 87: explicit Device(uint objid_);
1.1 root 88: public:
1.1.1.15 root 89: ~Device() override;
1.1 root 90:
91: public:
92: // 初期化は以下の手順で行う。
93: // 1. コンストラクタ
94: // メンバ変数の初期値代入などを行う。失敗するケースは考慮していない。
1.1.1.4 root 95: // gConfig の内部変数の追加はここ(か2.の動的コンストラクション)で
96: // 行うこと。この時点ですでに gConfig の設定内容の参照は可能だが、
1.1.1.14 root 97: // エラーが出るものはここではなく Create() か Init() で処理すること。
1.1.1.12 root 98: // putmsg() は使えない。
1.1 root 99: //
100: // 2. Create() ... 動的コンストラクション
101: // 必要なら設定ファイルによって可変なオブジェクトのコンストラクトを行う。
1.1.1.14 root 102: // 例えば SCSI ドライブなどが該当する。Create() で作成したインスタンスの
103: // Create() もこのフェーズで呼ばれる。
104: // ここでも gConfig の参照および内部変数の登録は可能、エラー終了する
105: // 可能性のあるものも処理できる。
1.1.1.17 root 106: // 継承クラスの Create() は Device::Create() を呼ぶ必要はない。
1.1.1.14 root 107: // putmsg() は使えない。
1.1 root 108: //
1.1.1.17 root 109: // 3. EarlyInit() ... ログ出力の初期化
110: // ここですべての Device に対してログ出力のための変数を初期化する。
111: // ただし putmsg() が使えるのは 4. 以降。
112: // これは override しない。
113: //
114: // 4. 設定とログの締め切り。
115: // これ以降 gConfig の変更は出来ない。
116: // またログの割り当てを受ける Object 由来のオブジェクトはすべて出揃って
117: // いる必要がある。
118: // 4.1 この時点で gConfig の内容は確定したので、--show-config を行う。
119: // 4.2 ParseLogopt() ... -L オプションの処理。
120: //
121: // 5. Create2() ... 動的コンストラクションその2
122: // 作成にあたってログ出力をしたいホストドライバのためのフェーズ。
123: // ログは既存のものから従属するしか出来ない。
124: // putmsg() は使える。
125: // EarlyInit() は Create2() のループ後に改めて呼ばれる。
1.1 root 126: //
1.1.1.17 root 127: // 6. ParseMonitors() ... -M オプションの処理
128: // (GUI 版のみ) この時点で Monitor はすべて登録されている必要がある。
1.1.1.10 root 129: //
1.1.1.17 root 130: // 7. Init() ... 初期化
1.1.1.13 root 131: // この時点で Object 由来のオブジェクトはすべて出揃っているため、他の
1.1.1.17 root 132: // Object はすべてアクセス可能。
133: // 継承クラスは Device::Init() を呼ぶ必要はないが、子クラスが親クラスの
134: // Init() を呼ぶことを要求することはあるかもしれない。
1.1.1.12 root 135: // gConfig の設定項目のうち内容によってエラー終了する可能性があるものは
1.1.1.14 root 136: // ここまでに処理する。
1.1.1.15 root 137: // 複数のオブジェクトが同じ設定項目を処理しないようにすること (複数で
138: // 別々に読んでその際の範囲チェックに齟齬が発生するとかを避けるため)。
1.1.1.13 root 139: // Object 同士は完全に相互アクセス可能だが、Init() 自身の依存関係
140: // (A::Init() で設定した値を B::Init() が参照する必要があるケース) に
141: // ついては vm.cpp (などコンテナデバイス) 内のコンストラクタの順序で
142: // 手動調整すること (循環参照不可)。
1.1.1.12 root 143: //
1.1.1.17 root 144: // 8. StartThread() ... スレッド起動
1.1 root 145: //
1.1.1.18! root 146: // 9. ResetHard(true) ... 電源オン
1.1.1.17 root 147:
148: // ログの初期化。
149: void EarlyInit();
1.1 root 150:
151: // 動的コンストラクション。
1.1.1.12 root 152: // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err()
153: // 系でエラーメッセージを表示して false を返すこと。
1.1 root 154: virtual bool Create();
155:
1.1.1.17 root 156: // 動的コンストラクションその2。
157: // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err()
158: // 系でエラーメッセージを表示して false を返すこと。
159: // putmsg() は使える。
160: virtual bool Create2();
161:
1.1 root 162: // 初期化。
1.1.1.12 root 163: // 成功すれば true を返す。失敗なら warn() 系、あるいは gConfig->Err()
164: // 系でエラーメッセージを表示して false を返すこと。
1.1 root 165: virtual bool Init();
166:
1.1.1.12 root 167: // 電源オンもしくはリセット。
168: // true なら電源オン、false ならリセット。
1.1.1.8 root 169: // このデバイスがどのタイミングでリセットされるかは VM による。
170: // X68030 なら vm_x68k.cpp 内のコメント参照。
171: // LUNA は詳細不明。
1.1.1.12 root 172: virtual void ResetHard(bool poweron);
173:
174: // 電源オフ
175: virtual void PowerOff();
176:
177: // ログ出力
178: void putlogn(const char *fmt, ...) const override __printflike(2, 3);
1.1.1.13 root 179:
180: protected:
181: // ログに時刻と PPC を出すために必要
1.1.1.16 root 182: MainMPUDevice *mpu {};
1.1.1.13 root 183: Scheduler *scheduler {};
1.1 root 184: };
185:
186: class IODevice : public Device
187: {
1.1.1.4 root 188: using inherited = Device;
1.1 root 189: protected:
1.1.1.16 root 190: explicit IODevice(uint objid_);
1.1 root 191: public:
1.1.1.15 root 192: ~IODevice() override;
1.1 root 193:
194: public:
1.1.1.16 root 195: // メイン CPU からのデバイスの読み込み。
196: // busaddr.Addr にアドレス、busaddr.Size に要求バイト数がセットされている。
197: // busdata.Size にはポートサイズ (応答バイト数) を返す。
198: // 戻り値 busdata.Data は下詰めし、不要な上位バイトはクリアして返すこと。
199: virtual busdata Read(busaddr addr);
200:
201: // メイン CPU からのデバイスへの書き込み。
202: // busaddr.Addr にアドレス、busaddr.Size に要求バイト数がセットされている。
203: // data は Size バイト分が下詰めされており、上位の不要バイトはクリア済み。
204: // 戻り値の busdata.Size にはポートサイズを返すこと。
205: virtual busdata Write(busaddr addr, uint32 data);
206:
207: // メイン CPU からのバーストアクセス。
208: // addr (16バイト境界) からの 16 バイトを転送してウェイトと OK を返す。
209: // dst/src の uint32 はホストエンディアン。
210: // バースト転送をサポートしてなければ BusData::BusErr を返す。
211: virtual busdata ReadBurst16(busaddr addr, uint32 *dst);
212: virtual busdata WriteBurst16(busaddr addr, const uint32 *src);
213:
214: // XP からのデバイスの読み込み。
215: // 戻り値は busdata.Data の1バイトと必要なら Wait。他は使用しない。
216: virtual busdata Read1(uint32 addr);
217:
218: // XP からのデバイスへの書き込み。
219: // data は1バイト。
220: // 戻り値は busdata.Wait のみ。他は使用しない。
221: virtual busdata Write1(uint32 addr, uint32 data);
1.1.1.13 root 222:
1.1.1.16 root 223: // Peek1() はデバッガアクセスで読み込んだ値を (uint32) で返す。
1.1.1.13 root 224: // バイトアクセスした時に読める値ではなく、現在このアドレスに見えている
1.1.1.16 root 225: // であろう値。バスエラーなら BusData::BusErr を返す。
226: virtual busdata Peek1(uint32 addr);
1.1 root 227:
1.1.1.16 root 228: // Poke1() はデバッガからこのアドレス(メモリ)へ書き込む。
1.1.1.13 root 229: // メモリでない領域 (レジスタなど) は書き込み不可。
1.1.1.15 root 230: // data が (int32 で) 非負なら data の下位8ビットを書き込む。
231: // 書き込めれば true、書き込めなければ false を返す。
1.1.1.13 root 232: // data が (int32 で) 負なら addr への書き込み可否の問い合わせで、
1.1.1.15 root 233: // 書き込み可能なら true、書き込み不可能なら false を返す。
1.1.1.16 root 234: virtual bool Poke1(uint32 addr, uint32 data);
1.1 root 235: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.