Annotation of nono/vm/windrv.h, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2023 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // Windrv (相当)
                      9: //
                     10: 
                     11: #pragma once
                     12: 
                     13: #include "device.h"
                     14: #include <array>
                     15: #include <deque>
                     16: #include <map>
                     17: 
                     18: class HostWindrv;
                     19: class MainbusDevice;
                     20: class MPU680x0Device;
                     21: class WindrvDevice;
                     22: 
                     23: // Human68k の定数とか構造体とか。
                     24: class Human68k
                     25: {
                     26:  public:
1.1.1.2   root       27:        static const uint MAX_PATH = 96;
1.1       root       28: 
                     29:        static const uint8 ATTR_RDONLY  = 0x01;
                     30:        static const uint8 ATTR_HIDDEN  = 0x02;
                     31:        static const uint8 ATTR_SYSTEM  = 0x04;
                     32:        static const uint8 ATTR_VOLUME  = 0x08;
                     33:        static const uint8 ATTR_DIR             = 0x10;
                     34:        static const uint8 ATTR_ARCHIVE = 0x20;
                     35: 
                     36:        // 標準(<fcntl.h>) の O_RDONLY とかは #define なので、
                     37:        // ここで別の名前空間で同名の定数を定義するとかが出来ない。
                     38:        static const int OPEN_RDONLY    = 0;
                     39:        static const int OPEN_WRONLY    = 1;
                     40:        static const int OPEN_RDWR              = 2;
                     41: 
                     42: #define DEF static const uint32
                     43:        // エラーコード(下位バイト)
                     44:        DEF ERR_INVALID_UNIT    = 0x0001;       // 無効なユニット番号
                     45:        DEF ERR_INVALID_COMMAND = 0x0003;       // 無効なコマンド
                     46:        DEF ERR_WRITE                   = 0x000a;       // 書き込みエラー
                     47:        DEF ERR_READ                    = 0x000b;       // 読み込みエラー
                     48:        DEF ERR_MISC                    = 0x000c;       // エラーが発生しました
                     49:        DEF ERR_WRITE_PROTECT   = 0x000e;       // 書き込み保護されている
                     50:        // エラーコード(上位バイト)
                     51:        DEF ERR_IGNORE                  = 0x4000;       // 無視(I)
                     52:        DEF ERR_RETRY                   = 0x2000;       // 再実行(R)
                     53:        DEF ERR_ABORT                   = 0x1000;       // 中止(A)
                     54:        // 合成したもの
                     55:        DEF ERR_INVALID_UNIT_IA    = ERR_INVALID_UNIT | ERR_IGNORE | ERR_ABORT;
                     56:        DEF ERR_INVALID_COMMAND_IA = ERR_INVALID_COMMAND | ERR_IGNORE | ERR_ABORT;
                     57: 
                     58:        // ステータスコード
                     59:        DEF RES_INVALID_FUNC    =  -1; // 無効なファンクションコード
                     60:        DEF RES_FILE_NOT_FOUND  =  -2; // ファイルが見付からない
                     61:        DEF RES_DIR_NOT_FOUND   =  -3; // ディレクトリが見付からない
                     62:        DEF RES_TOO_MANY_HANDLE =  -4; // オープンしているハンドルが多い
                     63:        DEF RES_NOT_A_FILE              =  -5; // ディレクトリ・ボリュームは不可
                     64:        DEF RES_NOT_OPENED              =  -6; // ハンドルはオープンされていない
                     65:        DEF RES_INVALID_MEM             =  -7; // メモリ管理領域が不正
                     66:        DEF RES_NO_MEMORY               =  -8; // メモリが足りない
                     67:        DEF RES_INVALID_PTR             =  -9; // ポインタが無効
                     68:        DEF RES_INVALID_ENV             = -10; // 環境が不正
                     69:        DEF RES_ILLEGAL_FORMAT  = -11; // 実行ファイルのフォーマットが不正
                     70:        DEF RES_INVALID_MODE    = -12; // オープンのアクセスモードが不正
                     71:        DEF RES_INVALID_PATH    = -13; // ファイル名が不正
                     72:        DEF RES_INVALID_PARAM   = -14; // パラメータが不正
                     73:        DEF RES_INVALID_DRIVE   = -15; // ドライブ指定が不正
                     74:        DEF RES_CURRENT_DIR             = -16; // カレントディレクトリは削除出来ない
                     75:        DEF RES_NO_IOCTRL               = -17; // IOCTRL 出来ないデバイス
                     76:        DEF RES_LAST_FILE               = -18; // これ以上ファイルが見付からない
                     77:        DEF RES_CANNOT_WRITE    = -19; // ファイルは書き込み出来ない
                     78:        DEF RES_DIR_EXISTS              = -20; // ディレクトリはすでに存在する
                     79:        DEF RES_CANNOT_DELETE   = -21; // ファイルがあるので削除出来ない
                     80:        DEF RES_CANNOT_RENAME   = -22; // ファイルがあるのでリネーム出来ない
                     81:        DEF RES_DISK_FULL               = -23; // ディスクが一杯
                     82:        DEF RES_DIR_FULL                = -24; // ディレクトリが一杯
                     83:        DEF RES_CANNOT_SEEK             = -25; // シーク出来ない
                     84:        DEF RES_SUPERVISOR              = -26; // スーパバイザ状態でスーパバイザ指定
                     85:        DEF RES_THREAD_EXISTS   = -27; // スレッド名が存在する
                     86:        DEF RES_PROCESS_BUF             = -28; // プロセス間通信バッファが書き込み禁止
                     87:        DEF RES_BACKGROUND              = -29; // バックグラウンドプロセスを起動出来ない
                     88:        DEF RES_NO_LOCKBUF              = -32; // ロック領域が足りない
                     89:        DEF RES_LOCKED                  = -33; // ロックされている
                     90:        DEF RES_DRIVE_OPENED    = -34; // ドライブのハンドルはオープンされている
                     91:        DEF RES_TOO_MANY_LINKS  = -35; // シンボリックリンクのネストが多い
                     92:        DEF RES_FILE_EXISTS             = -80; // ファイルが存在する
                     93: #undef DEF
                     94: 
                     95:        struct FILES {
                     96:                uint8 sattr;                            // $00: 検索する属性
                     97:                uint8 drive;                            // $01: ドライブ番号
                     98:                uint32 sector;                          // $02: ディレクトリのセクタ番号
                     99:                                                                        //      (DOS _FILES の先頭アドレスで代用)
                    100:                //uint16 sector2;                       // $06: 詳細不明、未使用
                    101:                uint16 offset;                          // $08: ディレクトリの位置、詳細不明
                    102:                //char[8] name1;                        // $0a: 作業用ファイル名、未使用
                    103:                //char[3] ext;                          // $12: 作業用拡張子、未使用
                    104:                uint8 attr;                                     // $15: ファイル属性
                    105:                uint16 time;                            // $16: 最終更新時刻
                    106:                uint16 date;                            // $18: 最終更新日付
                    107:                uint32 size;                            // $1a: ファイルサイズ
                    108:                //char[23] name;                        // $1e: ファイル名(フル)
                    109: 
                    110:                // ファイル名。
                    111:                // マルチバイト文字をサポートした場合はここはホスト文字コードの
                    112:                // ファイル名なので、ゲスト文字コード(Shift_JIS)で23バイトに
                    113:                // 収まってもホスト文字コードで23バイトで収まるとは限らない。
                    114:                std::string name;
                    115: 
                    116:                // (parent を通じて) 必要なフィールドだけを VM メモリに書き出す。
                    117:                void WriteToMem(WindrvDevice *parent, uint32 addr) const;
                    118:        };
                    119: 
                    120:        class FCB
                    121:        {
                    122:                // +$00,  6.B:  (内部使用)
                    123:                // +$06,  1.L: ファイルポインタ
                    124:                // +$0a,  1.L:  (内部使用)
                    125:                // +$0e,  1.B: オープンモード
                    126:                // +$0f, 21.B:  (内部使用)
                    127:                // +$24,  8.B: ファイル名1
                    128:                // +$2c,  3.B: 拡張子
                    129:                // +$2f,  1.B: ファイル属性
                    130:                // +$30, 10.B: ファイル名2
                    131:                // +$3a,  1.W: 最終更新時刻
                    132:                // +$3c,  1.W: 最終更新日付
                    133:                // +$3e,  1.W:  (内部使用)
                    134:                // +$40,  1.L: ファイルサイズ
                    135:                // +$44,  7.L:  (内部使用)
                    136:         public:
                    137:                FCB(WindrvDevice *parent_, uint32 addr_);
                    138: 
                    139:                // ここにコピーは持たず、都度 VM メモリを参照/更新する。
                    140:                // FCB はフィールドが多いわりに Open、Read などの各コマンドの
                    141:                // フィールドアクセスはまばらななので。
                    142:                uint32 GetPos() const;          // 現在位置取得
                    143:                void SetPos(uint32);            // 現在位置設定
                    144:                void AddPos(uint32);            // 現在位置を加算
                    145:                uint8 GetMode() const;          // オープンモード取得
                    146:                void SetDateTime(uint32);       // 日付時刻を設定
                    147:                uint32 GetSize() const;         // サイズ取得
                    148:                void SetSize(uint32);           // サイズ設定
                    149:                void SetName(const std::string& name1, const std::string& name2,
                    150:                        const std::string& ext);        // ファイル名を設定
                    151: 
                    152:                uint32 GetAddr() const { return addr; }
                    153: 
                    154:         protected:
                    155:                WindrvDevice *parent {};
                    156: 
                    157:         private:
                    158:                uint32 addr {};                         // FCB アドレス(検索キー)
                    159:        };
                    160: 
                    161:        struct capacity {
                    162:                uint16 avail_clusters;          // 空きクラスタ数
                    163:                uint16 total_clusters;          // 総クラスタ数
                    164:                uint16 sectors_per_cluster;
                    165:                uint16 bytes_per_sector;
                    166: 
                    167:                // (parent を通じて) VM メモリに書き出す。
                    168:                void WriteToMem(WindrvDevice *parent, uint32 addr) const;
                    169:        };
                    170: 
                    171:        struct DPB {
                    172:                uint16 sector_size;             // 1セクタあたりのバイト数
                    173:                uint8  cluster_size;    // 1クラスタあたりのセクタ数 - 1
                    174:                uint8  shift;                   // クラスタからセクタへのシフト数
                    175:                                                                // (bit7=%1 なら 16bit FAT ?)
                    176:                uint16 fat_sector;              // FAT の先頭セクタ番号
                    177:                uint8  fat_max;                 // FAT 領域の個数
                    178:                uint8  fat_size;                // 1つの FAT 領域のセクタ数
                    179:                uint16 file_max;                // ルートディレクトリの最大ファイル数
                    180:                uint16 data_sector;             // データ領域の先頭セクタ
                    181:                uint16 cluster_max;             // 総クラスタ数
                    182:                uint16 root_sector;             // ルートディレクトリの先頭セクタ番号
                    183:                uint8  media;                   // メディア ID
                    184: 
                    185:                // (parent を通じて) VM メモリに書き出す。
                    186:                void WriteToMem(WindrvDevice *parent, uint32 addr) const;
                    187:        };
                    188: 
                    189:        // 属性をデバッグ表示用文字列にする。
                    190:        static std::string AttrStr(uint8 attr);
                    191: 
                    192:        // オープンモードを表示用文字列にする。
                    193:        static std::string OpenModeStr(uint8 mode);
                    194: 
                    195:        // ステータスコード/エラーコードに対応するメッセージを返す。
                    196:        static const char *GetResultMsg(uint32 result);
                    197: 
                    198:        // UNIX 時刻から MS-DOS 形式の日付時刻を取得。
                    199:        // uint32 の上位が日付、下位が時刻で返す。
                    200:        static uint32 Unixtime2DateTime(time_t);
                    201: 
                    202:        // MS-DOS 形式の日付時刻から UNIX 時刻を取得。
                    203:        static time_t DateTime2Unixtime(uint32);
                    204: 
                    205:  private:
                    206:        static const char * const result_msg[];
                    207:        static const char * const err_msg[];
                    208: };
                    209: 
                    210: // 仮想ディレクトリエントリ
                    211: class VDirent
                    212: {
                    213:  public:
                    214:        VDirent(const std::string& name_, bool isdir_);
                    215: 
                    216:        // ここの属性は Valid かどうかと Dir/Archive(Regular) のみを使う。
                    217:        // Files/NFiles で拾う時は (タイムスタンプやサイズとともに)
                    218:        // 属性も改めてファイルシステムから拾う。
                    219:        bool IsValid() const    { return isvalid; }
                    220:        bool IsDir() const              { return isdir; }
                    221:        bool IsArchive() const  { return !isdir; }
                    222: 
                    223:        // このエントリを Human68k に見せないようにする。
                    224:        void Invalidate() { isvalid = false; }
                    225: 
                    226:        std::string name {};    // ホストファイル名。
                    227:        bool isdir {};                  // ディレクトリなら true、ファイルなら false。
                    228:        bool isvalid {};                // エントリが有効なら true。
                    229: };
                    230: 
                    231: // 仮想ディレクトリ構造
                    232: class VDir
                    233: {
                    234:  public:
                    235:        VDir();
                    236:        VDir(HostWindrv *host_, const std::string& path_);
                    237: 
                    238:        // ホスト相対パスを返す。
                    239:        const std::string& GetPath() const { return path; }
                    240: 
                    241:        // このディレクトリから name にマッチするエントリを返す。
                    242:        // 見付からなければ NULL を返す。
                    243:        const VDirent *MatchName(const std::string& name, bool want_exist) const;
                    244: 
                    245:        void Acquire();
                    246:        void Release();
                    247: 
                    248:        // 参照カウントを返す。
                    249:        int Refcount() const { return refcount; }
                    250: 
                    251:        // この VDir 構成時の mtime [nsec] を返す。
                    252:        uint64 GetMTime() const { return mtime; }
                    253: 
                    254:        // mtime を更新する。
                    255:        void SetMTime(uint64 mtime_) { mtime = mtime_; }
                    256: 
                    257:        // この VDir の参照時刻 [usec] を返す。
                    258:        uint64 GetATime() const { return atime; }
                    259: 
                    260:        // 参照時刻を更新する。
                    261:        void UpdateATime();
                    262: 
                    263:        // このディレクトリ内のエントリ。
                    264:        std::vector<VDirent> list {};
                    265: 
                    266:  private:
                    267:        // ホストでの相対パス。
                    268:        std::string path {};
                    269: 
1.1.1.3 ! root      270:        // ホストの対応ディレクトリの更新日時 [nsec]。
1.1       root      271:        // (st_mtimespec がある場合のみ使用する)
                    272:        uint64 mtime {};
                    273: 
                    274:        // この VDir を参照した実時刻 [usec]。
                    275:        // こっちは、キャッシュから追い出す人を決定するために使うので uint64。
                    276:        uint64 atime {};
                    277: 
                    278:        // 参照中のディレクトリを消さないようにするため。
                    279:        int refcount {};
                    280: 
                    281:        HostWindrv *host {};
                    282: };
                    283: 
                    284: // VDir を自動変数みたいに勝手にクローズしてほしい。
                    285: class AutoVDir
                    286: {
                    287:  public:
                    288:        AutoVDir(HostWindrv *host_, VDir *vdir_) {
                    289:                host = host_;
                    290:                vdir = vdir_;
                    291:        }
                    292:        ~AutoVDir();
                    293: 
                    294:        // vdir-> で VDir* をアクセスすることで透過っぽく見せる。
                    295:        VDir *operator->() const noexcept {
                    296:                return vdir;
                    297:        }
                    298: 
                    299:        // unique_ptr と同様に (bool) で有効かどうかを返す。
                    300:        explicit operator bool() const noexcept {
                    301:                return (vdir != NULL);
                    302:        }
                    303: 
                    304:  private:
                    305:        HostWindrv *host {};
                    306:        VDir *vdir {};
                    307: };
                    308: 
                    309: // FILES のこちら側のバッファ。
                    310: class FilesBuf
                    311: {
                    312:  public:
                    313:        FilesBuf(uint32 key_, HostWindrv *host_);
                    314:        void Init(uint32 key_, HostWindrv *host_);
                    315: 
                    316:        uint64 GetATime() const { return atime; }
                    317:        void UpdateATime();
                    318: 
                    319:  public:
                    320:        uint32 key {};                                  // FILES バッファアドレス
                    321:        HostWindrv *host {};                    // ホスト (ドライブ)
                    322:        std::string path {};                    // ホスト相対パス
                    323: 
                    324:        // マッチしたファイル名一覧。
                    325:        // Files/NFiles で取得するたびに先頭から削除していく方式。
                    326:        std::deque<std::string> list {};
                    327: 
                    328:        // 直近にマッチしたファイル名(ログ出力用)
                    329:        std::string fname {};
                    330: 
                    331:  private:
                    332:        uint64 atime {};
                    333: };
                    334: 
                    335: class Windrv
                    336: {
                    337:  public:
                    338:        // Human68k の FCB 構造体とホスト側で必要なメンバを集約したクラス。
                    339:        // ハンドルのように使う。
                    340:        class FCB : public Human68k::FCB
                    341:        {
                    342:                using inherited = Human68k::FCB;
                    343:         public:
                    344:                FCB(WindrvDevice *, uint32 addr_, HostWindrv *host_);
                    345: 
                    346:                void Close();
                    347: 
                    348:                // 対応するホストドライバ
                    349:                HostWindrv *host {};
                    350:                // ファイルディスクリプタ
                    351:                int fd {};
                    352:        };
                    353: 
                    354:        // いずれオプションになるかも知れないが。
                    355:        static const bool option_case_sensitive = false;
                    356: };
                    357: 
                    358: class WindrvDevice : public IODevice, Windrv
                    359: {
                    360:        using inherited = IODevice;
                    361:        friend class Human68k;
                    362:        friend class Windrv;
                    363: 
                    364:        // Human68k の NAMESTS 構造体を読み込んだもの。
                    365:        // windrv.sys では、Windrv デバイスから windrv.sys にこの構造体を返す
                    366:        // ケースはなく、すべて windrv.sys から Windrv デバイスへの方向なので、
                    367:        // 受け取った時点でホスト側に都合のいいように加工して保持する。
                    368:        class NAMESTS
                    369:        {
                    370:                // +$00, 1.B: ワイルドカード文字数
                    371:                // +$01, 1.B: ドライブ番号 (A:=0、B:=1、…)
                    372:                // +$02,65.B: パス
                    373:                // +$43, 8.B: ファイル名1 (余りは ' ' で埋める)
                    374:                // +$4b, 3.B: 拡張子 (余りは ' ' で埋める)
                    375:                // +$4e,10.B: ファイル名2 (余りは '\0' で埋める)
                    376:                //
                    377:                // NAMESTS 内のパスは '\' 区切り、最後にも '\' が付いて '\0' で終端、
                    378:                // らしいが、観測してると '\t'(\x09) 区切りで最後にも '\t' が付いて
                    379:                // '\0' で終端する文字列が来てる。なんだべ。
                    380:         public:
                    381:                static const int Size = 0x58;   // 構造体の大きさ
                    382:         private:
                    383:                std::string path;       // '/' 区切り
                    384:                std::string name1;      // パディングの ' ' を除いたもの
                    385:                std::string ext;        // パディングの ' ' を除いたもの
                    386:                std::string name2;      // パディングの '\0' を除いたもの
                    387:         public:
                    388:                int wildcard;
                    389:                int drive;
                    390: 
                    391:         public:
                    392:                // コンストラクタ
                    393:                NAMESTS(WindrvDevice *, uint32 addr);
                    394: 
                    395:                // drive, path を '/' 区切りで返す。
                    396:                std::string GetDrivePath() const;
                    397: 
                    398:                // path のみ('/' 区切り)を返す。
                    399:                const std::string& GetPath() const { return path; }
                    400: 
                    401:                // ファイル名(8+10.3)を返す。
                    402:                std::string GetName() const;
                    403: 
                    404:                const std::string& GetName1() const { return name1; }
                    405:                const std::string& GetName2() const { return name2; }
                    406:                const std::string& GetExt()   const { return ext; }
                    407: 
                    408:                // ドライブ、パス、ファイル名を返す。
                    409:                std::string GetFull() const;
                    410: 
                    411:                // ログ表示用のドライブ、パス文字列を返す。
                    412:                std::string PrintDrivePath() const;
                    413:        };
                    414: 
                    415:        // 最大ドライブ数
                    416:        static const int MaxDrives = 1;
                    417: 
                    418:        // FilesBuf の最大数
                    419:        static const int MaxFilesBuf = 32;      // (適当)
                    420: 
                    421:  public:
                    422:        WindrvDevice();
                    423:        ~WindrvDevice() override;
                    424: 
                    425:        bool Create() override;
                    426:        void SetLogLevel(int) override;
                    427:        bool Init() override;
                    428:        void ResetHard(bool poweron) override;
                    429: 
                    430:        // Windrv を組み込むなら true を返す。
                    431:        static bool IsWindrv();
                    432: 
1.1.1.2   root      433:  protected:
                    434:        // BusIO インタフェース
                    435:        static const uint32 NPORT = 0x2000;
                    436:        busdata ReadPort(uint32 offset);
                    437:        busdata WritePort(uint32 offset, uint32 data);
                    438:        busdata PeekPort(uint32 offset);
                    439:        bool PokePort(uint32 offset, uint32 data);
                    440: 
1.1       root      441:  private:
                    442:        uint32 GetIdent() const;
                    443:        void Execute();
                    444:        uint32 DispatchCommand();
                    445: 
                    446:        uint32 CmdInitialize();
                    447:        uint32 CmdCheckDir(HostWindrv *);
                    448:        uint32 CmdMakeDir(HostWindrv *);
                    449:        uint32 CmdRemoveDir(HostWindrv *);
                    450:        uint32 CmdRename(HostWindrv *);
                    451:        uint32 CmdDelete(HostWindrv *);
                    452:        uint32 CmdAttribute(HostWindrv *);
                    453:        uint32 CmdFiles(HostWindrv *);
                    454:        uint32 CmdNFiles(HostWindrv *);
                    455:        uint32 CmdCreate(HostWindrv *);
                    456:        uint32 CmdOpen(HostWindrv *);
                    457:        uint32 CmdClose(HostWindrv *);
                    458:        uint32 CmdRead(HostWindrv *);
                    459:        uint32 CmdWrite(HostWindrv *);
                    460:        uint32 CmdSeek(HostWindrv *);
                    461:        uint32 CmdFileTime(HostWindrv *);
                    462:        uint32 CmdGetCapacity(HostWindrv *);
                    463:        uint32 CmdCtrlDrive(HostWindrv *);
                    464:        uint32 CmdGetDPB(HostWindrv *);
                    465:        uint32 CmdDiskRead(HostWindrv *);
                    466:        uint32 CmdDiskWrite(HostWindrv *);
                    467:        uint32 CmdIoControl(HostWindrv *);
                    468:        uint32 CmdFlush(HostWindrv *);
                    469:        uint32 CmdCheckMedia(HostWindrv *);
                    470:        uint32 CmdLock(HostWindrv *);
                    471: 
                    472:        void SetResult(uint32);
                    473: 
                    474:        // result を表示用に整形して返す
                    475:        static std::string ResultStr(uint32 result);
                    476: 
                    477:        // メモリアクセス
                    478:        uint32 ReadMem8(uint32 addr) const;
                    479:        void WriteMem8(uint32 addr, uint32 data);
                    480:        uint32 ReadMem16(uint32 addr) const;
                    481:        void WriteMem16(uint32 addr, uint32 data);
                    482:        uint32 ReadMem32(uint32 addr) const;
                    483:        void WriteMem32(uint32 addr, uint32 data);
                    484:        uint32 ReadMemAddr(uint32 addr) const;
                    485:        void WriteMemAddr(uint32 addr, uint32 data);
                    486:        void ReadMem(void *dst, uint32 srcaddr, int len) const;
                    487:        void WriteMem(uint32 dstaddr, const void *src, int len);
                    488: 
                    489:        uint32 FilesCommon(FilesBuf *, uint32 addr);
                    490:        bool MatchFilename(const std::string& fname, const NAMESTS& ns) const;
                    491:        static bool MatchWildcard(const std::string& fn, const std::string& pn);
                    492: 
                    493:        // addr に対応する FILES バッファを探す。
                    494:        FilesBuf *SearchFilesBuf(uint32 addr) const;
                    495:        // addr に対応する FILES バッファを作成して返す。
                    496:        FilesBuf *AllocFilesBuf(uint32 addr, HostWindrv *);
                    497: 
                    498:        // addr に対応する FCB を探す。
                    499:        Windrv::FCB *SearchFCB(uint32 addr) const;
                    500:        // FCB を登録する。
                    501:        uint32 AddFCB(const Windrv::FCB&);
                    502:        // FCB を解放して削除する。
                    503:        void FreeFCB(Windrv::FCB *);
                    504: 
                    505:        uint32 a5 {};
                    506:        uint32 command {};
                    507: 
                    508:        // ログ表示用
                    509:        std::string cmdname {};
                    510: 
                    511:        std::array<std::unique_ptr<HostWindrv>, MaxDrives> hosts /*{}*/;
                    512: 
                    513:        std::map<uint32, FilesBuf*> filesmap {};
                    514: 
                    515:        std::map<uint32, FCB*> fcbmap {};
                    516: 
                    517:        MainbusDevice *mainbus {};
                    518:        MPU680x0Device *mpu680x0 {};
                    519: };

unix.superglobalmegacorp.com

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