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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2021 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.2   root        7: //
                      8: // Human68k?
                      9: //
                     10: 
1.1       root       11: #pragma once
                     12: 
                     13: #include "device.h"
                     14: #include "mpu.h"
                     15: #include <array>
                     16: 
1.1.1.3 ! root       17: class MPU680x0Device;
        !            18: class MPU88xx0Device;
        !            19: class Scheduler;
1.1       root       20: 
                     21: // 謎の機種非依存 Human68k(?) システムコール
                     22: class HumanMI : public Object
                     23: {
                     24:        using inherited = Object;
                     25:  protected:
                     26:        // DOS コールの引数について
                     27:        //
                     28:        // m68k では引数はスタックに積まれる (本来の仕様のまま)。
                     29:        // m88k では、m88k のサブルーチン呼び出し規約を真似てレジスタに置くことに
                     30:        // する。ただしその際のレジスタは本来 r2..r9 固定だが、ここでは rS1 で
                     31:        // その先頭レジスタを指定できることにする。
                     32:        // どちらも Pop16()、Pop32() を使って引数を前から順番に取り出すことで
                     33:        // その差を吸収する。
                     34:        //
                     35:        // 例えば DOS _OPEN は第1引数が 32bit ポインタ、第1引数が 16bit の mode
                     36:        // なので、m68k では以下のようにコールする。
                     37:        //
                     38:        //              move.w  #MODE,-(sp)
                     39:        //              pea             nameptr
                     40:        //              DOS             _OPEN
                     41:        //              addq.l  #6,sp
                     42:        //
                     43:        // m88k からこの DOS コールを呼ぶ際は、例えば引数を r4 以降に置き、
                     44:        // 戻り値を r2 で受け取りたい場合は以下のようになる。
                     45:        //
                     46:        //              or.u    r4, r0, #(nameptr).Hi
                     47:        //              or              r4, r4, #(nameptr).Lo
                     48:        //              or              r5, r0, #mode
                     49:        //              doscall r2, r4, #_OPEN
                     50:        //
                     51:        // どちらの場合でも HumanMI は
                     52:        //
                     53:        //              ptr  = Pop32();
                     54:        //              mode = Pop16();
                     55:        //
                     56:        // として引数を取り出す。
                     57: 
                     58:        virtual uint64 Pop16() = 0;
                     59:        virtual uint64 Pop32() = 0;
                     60: 
                     61:        // レジスタにアクセスする。
                     62:        // レジスタ番号 rn は 機種依存。
                     63:        virtual uint32 ReadReg(int rn) = 0;
                     64:        virtual void WriteReg(int rn, uint32 data) = 0;
                     65: 
                     66:        // 結果をセットする。
                     67:        // m68k の場合は d0.l に格納される。
                     68:        // m88k の場合は rD に格納される。
                     69:        virtual void Result(uint32 data) = 0;
                     70: 
                     71:  public:
                     72:        HumanMI();
                     73:        virtual ~HumanMI();
                     74: 
                     75:        virtual bool Init() = 0;
                     76: 
                     77:        // CPU からのシステムコール呼び出しを受け取る口。
                     78:        // コール番号を解釈して引数リストを作る。
                     79:        virtual bool SysCallEntry() = 0;
                     80: 
                     81:        // バスアクセス
                     82:        uint64 Read8(uint32 addr) const { return gMPU->Read8(addr); }
                     83:        uint64 Read16(uint32 addr) const { return gMPU->Read16(addr); }
                     84:        uint64 Read32(uint32 addr) const { return gMPU->Read32(addr); }
                     85:        uint64 Write8(uint32 addr, uint32 data) const {
                     86:                return gMPU->Write8(addr, data); }
                     87:        uint64 Write16(uint32 addr, uint32 data) const {
                     88:                return gMPU->Write16(addr, data); }
                     89:        uint64 Write32(uint32 addr, uint32 data) const {
                     90:                return gMPU->Write32(addr, data); }
                     91: 
                     92: 
                     93:        // システムコール
                     94:        // システムコールは HumanMIFunc で、未実装など、エミュレートできないとき
                     95:        // false を返す。
                     96:        // システムコール自体のゲスト的なエラーは Result() 経由でゲストに
                     97:        // 伝えられる。
                     98: 
                     99:        using HumanMIFunc = bool (HumanMI::*)(void);
                    100:        std::array<HumanMIFunc, 256> scTable {};
                    101: 
                    102:        bool DOS_EXIT();
                    103:        bool DOS_GETCHAR();
                    104:        bool DOS_PUTCHAR();
                    105:        bool DOS_COMINP() { return false; }
                    106:        bool DOS_COMOUT() { return false; }
                    107:        bool DOS_PRNOUT() { return false; }
                    108:        bool DOS_INPOUT() { return false; }
                    109:        bool DOS_INKEY() { return false; }
                    110:        bool DOS_GETC() { return false; }
                    111:        bool DOS_PRINT();
                    112:        bool DOS_GETS() { return false; }
                    113:        bool DOS_KEYSNS() { return false; }
                    114:        bool DOS_KFLUSH() { return false; }
                    115:        bool DOS_FFLUSH() { return false; }
                    116:        bool DOS_CHGDRV() { return false; }
                    117:        bool DOS_DRVCTRL() { return false; }
                    118: 
                    119:        bool DOS_CONSNS() { return false; }
                    120:        bool DOS_PRNSNS() { return false; }
                    121:        bool DOS_CINSNS() { return false; }
                    122:        bool DOS_COUTSNS() { return false; }
                    123:        bool DOS_FATCHK() { return false; }
                    124:        bool DOS_HENDSP() { return false; }
                    125:        bool DOS_CURDRV() { return false; }
                    126:        bool DOS_GETSS() { return false; }
                    127:        bool DOS_FGETC() { return false; }
                    128:        bool DOS_FGETS() { return false; }
                    129:        bool DOS_FPUTC() { return false; }
                    130:        bool DOS_FPUTS() { return false; }
                    131:        bool DOS_ALLCLOSE() { return false; }
                    132: 
                    133:        bool DOS_SUPER() { return false; }
                    134:        bool DOS_FNCKEY() { return false; }
                    135:        bool DOS_KNJCTRL() { return false; }
                    136:        bool DOS_CONCTRL() { return false; }
                    137:        bool DOS_KEYCTRL() { return false; }
                    138:        bool DOS_INTVCS() { return false; }
                    139:        bool DOS_PSPSET() { return false; }
                    140:        bool DOS_GETTIM2() { return false; }
                    141:        bool DOS_SETTIM2() { return false; }
                    142:        bool DOS_NAMESTS() { return false; }
                    143:        bool DOS_GETDATE() { return false; }
                    144:        bool DOS_SETDATE() { return false; }
                    145:        bool DOS_GETTIME() { return false; }
                    146:        bool DOS_SETTIME() { return false; }
                    147:        bool DOS_VERIFY() { return false; }
                    148:        bool DOS_DUP0() { return false; }
                    149: 
                    150:        bool DOS_VERNUM() { return false; }
                    151:        bool DOS_KEEPPR() { return false; }
                    152:        bool DOS_GETDPB() { return false; }
                    153:        bool DOS_BREAKCK() { return false; }
                    154:        bool DOS_DRVXCHG() { return false; }
                    155:        bool DOS_INTVCG() { return false; }
                    156:        bool DOS_DSKFRE() { return false; }
                    157:        bool DOS_NAMECK() { return false; }
                    158:        bool DOS_MKDIR() { return false; }
                    159:        bool DOS_RMDIR() { return false; }
                    160:        bool DOS_CHDIR() { return false; }
                    161:        bool DOS_CREATE() { return false; }
                    162:        bool DOS_OPEN() { return false; }
                    163:        bool DOS_CLOSE() { return false; }
                    164:        bool DOS_READ() { return false; }
                    165: 
                    166:        bool DOS_WRITE();
                    167:        bool DOS_DELETE() { return false; }
                    168:        bool DOS_SEEK() { return false; }
                    169:        bool DOS_CHMOD() { return false; }
                    170:        bool DOS_IOCTRL() { return false; }
                    171:        bool DOS_DUP() { return false; }
                    172:        bool DOS_DUP2() { return false; }
                    173:        bool DOS_CURDIR() { return false; }
                    174:        bool DOS_MALLOC() { return false; }
                    175:        bool DOS_MFREE() { return false; }
                    176:        bool DOS_SETBLOCK();
                    177:        bool DOS_EXEC() { return false; }
                    178:        bool DOS_EXIT2();
                    179:        bool DOS_WAIT() { return false; }
                    180:        bool DOS_FILES() { return false; }
                    181:        bool DOS_NFILES() { return false; }
                    182: 
                    183:        bool DOS_SETPDB() { return false; }
                    184:        bool DOS_GETPDB() { return false; }
                    185:        bool DOS_SETENV() { return false; }
                    186:        bool DOS_GETENV() { return false; }
                    187:        bool DOS_VERIFYG() { return false; }
                    188:        bool DOS_COMMON() { return false; }
                    189:        bool DOS_RENAME() { return false; }
                    190:        bool DOS_FILEDATE() { return false; }
                    191:        bool DOS_MALLOC2() { return false; }
                    192:        bool DOS_MAKETMP() { return false; }
                    193:        bool DOS_NEWFILE() { return false; }
                    194:        bool DOS_LOCK() { return false; }
                    195:        bool DOS_ASSIGN() { return false; }
                    196: 
                    197:        bool DOS_FFLUSH_SET() { return false; }
                    198:        bool DOS_OS_PATCH() { return false; }
                    199:        bool DOS_GETFCB() { return false; }
                    200:        bool DOS_S_MALLOC() { return false; }
                    201:        bool DOS_S_MFREE() { return false; }
                    202:        bool DOS_S_PROCESS() { return false; }
                    203: 
                    204:        bool DOS_EXITVC() { return false; }
                    205:        bool DOS_CTRLVC() { return false; }
                    206:        bool DOS_ERRJVC() { return false; }
                    207:        bool DOS_DISKRED() { return false; }
                    208:        bool DOS_DISKWRT() { return false; }
                    209:        bool DOS_INDOSFLG() { return false; }
                    210:        bool DOS_SUPER_JSR() { return false; }
                    211:        bool DOS_BUS_ERR() { return false; }
                    212:        bool DOS_OPEN_PR() { return false; }
                    213:        bool DOS_KILL_PR() { return false; }
                    214:        bool DOS_GET_PR() { return false; }
                    215:        bool DOS_SUSPEND_PR() { return false; }
                    216:        bool DOS_SLEEP_PR() { return false; }
                    217:        bool DOS_SEND_PR() { return false; }
                    218:        bool DOS_TIME_PR() { return false; }
                    219:        bool DOS_CHANGE_PR() { return false; }
                    220: 
                    221:        // エラーコード
                    222:        struct Ecode {
                    223:                int code;
                    224:                std::string msg;
                    225:        };
                    226: 
                    227:        const Ecode E_OK                        {   0, "" };
                    228:        const Ecode E_INVALID_SC        {  -1, "Invalid system call" };
                    229:        const Ecode E_FILE_NOTFOUND     {  -2, "File not found" };
                    230:        const Ecode E_DIR_NOTFOUND      {  -3, "Directory not found" };
                    231:        const Ecode E_MANY_OPEN         {  -4, "Too many open" };
                    232:        const Ecode E_ACCESS            {  -5, "Access denied" };
                    233:        const Ecode E_NO_HANDLE         {  -6, "Handle not open" };
                    234:        const Ecode E_BROKEN_MD         {  -7, "Broken memory discriptor" };
                    235:        const Ecode E_MEMORY            {  -8, "Not enough memory" };
                    236:        const Ecode E_INVALID_MD        {  -9, "Invalid memory discriptor" };
                    237:        const Ecode E_INVALID_ENV       { -10, "Invalid environment" };
                    238:        const Ecode E_BAD_EXEC          { -11, "Bad executable format" };
                    239:        const Ecode E_BAD_OPEN          { -12, "Bad open mode" };
                    240:        const Ecode E_INVALID_FILE      { -13, "Invalid filename" };
                    241:        const Ecode E_INVALID_PARAM     { -14, "Invalid parameter" };
                    242:        const Ecode E_INVALID_DRIVE     { -15, "Invalid drive" };
                    243:        const Ecode E_DEL_CURDIR        { -16, "Can not delete curdir" };
                    244:        const Ecode E_INVALID_IOCTL     { -17, "Invalid ioctrl" };
                    245:        const Ecode E_NO_FILE           { -18, "No more files" };
                    246:        const Ecode E_CANT_WRITE        { -19, "Can not write file" };
                    247:        const Ecode E_DIR_ARE_REG       { -20, "Directory already registered" };
                    248:        const Ecode E_CANT_DEL          { -21, "Can not delete" };
                    249:        const Ecode E_CANT_RENAME       { -22, "Can not rename" };
                    250:        const Ecode E_DISK_FULL         { -23, "Disk full" };
                    251:        const Ecode E_DIR_FULL          { -24, "Directory full" };
                    252:        const Ecode E_CANT_SEEK         { -25, "Can not seek" };
                    253:        const Ecode E_ARE_SUPER         { -26, "Already supervisor" };
                    254:        const Ecode E_TH_ARE_EXIST      { -27, "Thread already exists" };
                    255:        const Ecode E_CANT_IPC          { -28, "Can not write IPC" };
                    256:        const Ecode E_MANY_PROC         { -29, "Too many process" };
                    257: 
                    258:        const Ecode E_MANY_LOCK         { -32, "Too many locks" };
                    259:        const Ecode E_HANDLE_LOCKED     { -33, "Handle locked" };
                    260:        const Ecode E_DRIVE_ARE_OP      { -34, "Drive already open" };
                    261:        const Ecode E_MANY_SYMLINK      { -35, "Too many nest symlink" };
                    262: 
                    263:        const Ecode E_FILE_EXIST        { -80, "File exist" };
                    264: 
                    265:  protected:
                    266:        bool Dispatch();
                    267: 
                    268:        void RequestExit(int code);
                    269: 
1.1.1.2   root      270:        uint scid {};           // 実行中のシステムコール番号
1.1.1.3 ! root      271: 
        !           272:        Scheduler *scheduler {};
1.1       root      273: };
                    274: 
                    275: // m680x0 に合わせたインタフェース。
                    276: class HumanMD_m680x0 : public HumanMI
                    277: {
                    278:  public:
                    279:        bool Init() override;
                    280:        bool SysCallEntry() override;
                    281:  protected:
                    282:        uint64 Pop16() override;
                    283:        uint64 Pop32() override;
                    284:        uint32 ReadReg(int rn) override;
                    285:        void WriteReg(int rn, uint32 data) override;
                    286:        void Result(uint32 data) override;
                    287: 
                    288:  protected:
                    289:        // システムコール時点の SP。
                    290:        // 引数の取り出しにより変化する。
1.1.1.2   root      291:        uint32 sp {};
1.1       root      292: 
1.1.1.3 ! root      293:        MPU680x0Device *mpu {};
1.1       root      294: };
                    295: 
                    296: // m88xx0 に合わせたインタフェース。
                    297: class HumanMD_m88xx0 : public HumanMI
                    298: {
                    299:  public:
                    300:        bool Init() override;
                    301:        bool SysCallEntry() override;
                    302:  protected:
                    303:        uint64 Pop16() override;
                    304:        uint64 Pop32() override;
                    305:        uint32 ReadReg(int rn) override;
                    306:        void WriteReg(int rn, uint32 data) override;
                    307:        void Result(uint32 data) override;
                    308: 
                    309:  protected:
                    310:        // システムコール時点の rS。
                    311:        // 引数の取り出しにより変化する。
1.1.1.2   root      312:        uint32 rs {};
1.1       root      313:        // システムコール時点の rD。
1.1.1.2   root      314:        uint32 rd {};
1.1       root      315: 
1.1.1.3 ! root      316:        MPU88xx0Device *cpu {};
1.1       root      317: };

unix.superglobalmegacorp.com

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