Annotation of nono/vm/human_mi.cpp, revision 1.1

1.1     ! root        1: //
        !             2: // nono
        !             3: // Copyright (C) 2021 nono project
        !             4: // Licensed under nono-license.txt
        !             5: //
        !             6: 
        !             7: #include "human_mi.h"
        !             8: 
        !             9: #include "mpu680x0.h"
        !            10: #include "mpu88xx0.h"
        !            11: #include "m88100acc.h"
        !            12: #include "scheduler.h"
        !            13: 
        !            14: bool human_m680x0_fline_callback(m68kcpu *cpu, void *arg);
        !            15: bool human_m88xx0_fline_callback(m88kcpu *cpu, void *arg);
        !            16: 
        !            17: HumanMI::HumanMI()
        !            18:        : inherited("HumanMI")
        !            19: {
        !            20: #define SC_DEF(id, name)       scTable[(id)] = &HumanMI::name
        !            21: 
        !            22:        SC_DEF(0x00, DOS_EXIT);
        !            23:        SC_DEF(0x01, DOS_GETCHAR);
        !            24:        SC_DEF(0x02, DOS_PUTCHAR);
        !            25:        SC_DEF(0x03, DOS_COMINP);
        !            26:        SC_DEF(0x04, DOS_COMOUT);
        !            27:        SC_DEF(0x05, DOS_PRNOUT);
        !            28:        SC_DEF(0x06, DOS_INPOUT);
        !            29:        SC_DEF(0x07, DOS_INKEY);
        !            30:        SC_DEF(0x08, DOS_GETC);
        !            31:        SC_DEF(0x09, DOS_PRINT);
        !            32:        SC_DEF(0x0a, DOS_GETS);
        !            33:        SC_DEF(0x0b, DOS_KEYSNS);
        !            34:        SC_DEF(0x0c, DOS_KFLUSH);
        !            35:        SC_DEF(0x0d, DOS_FFLUSH);
        !            36:        SC_DEF(0x0e, DOS_CHGDRV);
        !            37:        SC_DEF(0x0f, DOS_DRVCTRL);
        !            38: 
        !            39:        SC_DEF(0x10, DOS_CONSNS);
        !            40:        SC_DEF(0x11, DOS_PRNSNS);
        !            41:        SC_DEF(0x12, DOS_CINSNS);
        !            42:        SC_DEF(0x13, DOS_COUTSNS);
        !            43:        // $14..16 は欠番
        !            44:        SC_DEF(0x17, DOS_FATCHK);
        !            45:        SC_DEF(0x18, DOS_HENDSP);
        !            46:        SC_DEF(0x19, DOS_CURDRV);
        !            47:        SC_DEF(0x1a, DOS_GETSS);
        !            48:        SC_DEF(0x1b, DOS_FGETC);
        !            49:        SC_DEF(0x1c, DOS_FGETS);
        !            50:        SC_DEF(0x1d, DOS_FPUTC);
        !            51:        SC_DEF(0x1e, DOS_FPUTS);
        !            52:        SC_DEF(0x1f, DOS_ALLCLOSE);
        !            53: 
        !            54:        SC_DEF(0x20, DOS_SUPER);
        !            55:        SC_DEF(0x21, DOS_FNCKEY);
        !            56:        SC_DEF(0x22, DOS_KNJCTRL);
        !            57:        SC_DEF(0x23, DOS_CONCTRL);
        !            58:        SC_DEF(0x24, DOS_KEYCTRL);
        !            59:        SC_DEF(0x25, DOS_INTVCS);
        !            60:        SC_DEF(0x26, DOS_PSPSET);
        !            61:        SC_DEF(0x27, DOS_GETTIM2);
        !            62:        SC_DEF(0x28, DOS_SETTIM2);
        !            63:        SC_DEF(0x29, DOS_NAMESTS);
        !            64:        SC_DEF(0x2a, DOS_GETDATE);
        !            65:        SC_DEF(0x2b, DOS_SETDATE);
        !            66:        SC_DEF(0x2c, DOS_GETTIME);
        !            67:        SC_DEF(0x2d, DOS_SETTIME);
        !            68:        SC_DEF(0x2e, DOS_VERIFY);
        !            69:        SC_DEF(0x2f, DOS_DUP0);
        !            70: 
        !            71:        SC_DEF(0x30, DOS_VERNUM);
        !            72:        SC_DEF(0x31, DOS_KEEPPR);
        !            73:        SC_DEF(0x32, DOS_GETDPB);
        !            74:        SC_DEF(0x33, DOS_BREAKCK);
        !            75:        SC_DEF(0x34, DOS_DRVXCHG);
        !            76:        SC_DEF(0x35, DOS_INTVCG);
        !            77:        SC_DEF(0x36, DOS_DSKFRE);
        !            78:        SC_DEF(0x37, DOS_NAMECK);
        !            79:        // $38 は欠番
        !            80:        SC_DEF(0x39, DOS_MKDIR);
        !            81:        SC_DEF(0x3a, DOS_RMDIR);
        !            82:        SC_DEF(0x3b, DOS_CHDIR);
        !            83:        SC_DEF(0x3c, DOS_CREATE);
        !            84:        SC_DEF(0x3d, DOS_OPEN);
        !            85:        SC_DEF(0x3e, DOS_CLOSE);
        !            86:        SC_DEF(0x3f, DOS_READ);
        !            87: 
        !            88:        SC_DEF(0x40, DOS_WRITE);
        !            89:        SC_DEF(0x41, DOS_DELETE);
        !            90:        SC_DEF(0x42, DOS_SEEK);
        !            91:        SC_DEF(0x43, DOS_CHMOD);
        !            92:        SC_DEF(0x44, DOS_IOCTRL);
        !            93:        SC_DEF(0x45, DOS_DUP);
        !            94:        SC_DEF(0x46, DOS_DUP2);
        !            95:        SC_DEF(0x47, DOS_CURDIR);
        !            96:        SC_DEF(0x48, DOS_MALLOC);
        !            97:        SC_DEF(0x49, DOS_MFREE);
        !            98:        SC_DEF(0x4a, DOS_SETBLOCK);
        !            99:        SC_DEF(0x4b, DOS_EXEC);
        !           100:        SC_DEF(0x4c, DOS_EXIT2);
        !           101:        SC_DEF(0x4d, DOS_WAIT);
        !           102:        SC_DEF(0x4e, DOS_FILES);
        !           103:        SC_DEF(0x4f, DOS_NFILES);
        !           104: 
        !           105:        SC_DEF(0x80, DOS_SETPDB);
        !           106:        SC_DEF(0x81, DOS_GETPDB);
        !           107:        SC_DEF(0x82, DOS_SETENV);
        !           108:        SC_DEF(0x83, DOS_GETENV);
        !           109:        SC_DEF(0x84, DOS_VERIFYG);
        !           110:        SC_DEF(0x85, DOS_COMMON);
        !           111:        SC_DEF(0x86, DOS_RENAME);
        !           112:        SC_DEF(0x87, DOS_FILEDATE);
        !           113:        SC_DEF(0x88, DOS_MALLOC2);
        !           114:        SC_DEF(0x8a, DOS_MAKETMP);
        !           115:        SC_DEF(0x8b, DOS_NEWFILE);
        !           116:        SC_DEF(0x8c, DOS_LOCK);
        !           117:        // $8d..8e は欠番
        !           118:        SC_DEF(0x8f, DOS_ASSIGN);
        !           119: 
        !           120:        SC_DEF(0xaa, DOS_FFLUSH_SET);
        !           121:        SC_DEF(0xab, DOS_OS_PATCH);
        !           122:        SC_DEF(0xac, DOS_GETFCB);
        !           123:        SC_DEF(0xad, DOS_S_MALLOC);
        !           124:        SC_DEF(0xae, DOS_S_MFREE);
        !           125:        SC_DEF(0xaf, DOS_S_PROCESS);
        !           126: 
        !           127:        SC_DEF(0xf0, DOS_EXITVC);
        !           128:        SC_DEF(0xf1, DOS_CTRLVC);
        !           129:        SC_DEF(0xf2, DOS_ERRJVC);
        !           130:        SC_DEF(0xf3, DOS_DISKRED);
        !           131:        SC_DEF(0xf4, DOS_DISKWRT);
        !           132:        SC_DEF(0xf5, DOS_INDOSFLG);
        !           133:        SC_DEF(0xf6, DOS_SUPER_JSR);
        !           134:        SC_DEF(0xf7, DOS_BUS_ERR);
        !           135:        SC_DEF(0xf8, DOS_OPEN_PR);
        !           136:        SC_DEF(0xf9, DOS_KILL_PR);
        !           137:        SC_DEF(0xfa, DOS_GET_PR);
        !           138:        SC_DEF(0xfb, DOS_SUSPEND_PR);
        !           139:        SC_DEF(0xfc, DOS_SLEEP_PR);
        !           140:        SC_DEF(0xfd, DOS_SEND_PR);
        !           141:        SC_DEF(0xfe, DOS_TIME_PR);
        !           142:        SC_DEF(0xff, DOS_CHANGE_PR);
        !           143: }
        !           144: 
        !           145: HumanMI::~HumanMI()
        !           146: {
        !           147: }
        !           148: 
        !           149: bool
        !           150: HumanMI::Dispatch()
        !           151: {
        !           152:        if (scid < 0 || scid >= scTable.size()) {
        !           153:                // もともと定義されていないシステムコール。
        !           154:                return false;
        !           155:        }
        !           156:        auto func = scTable[scid];
        !           157:        if (func == nullptr) {
        !           158:                // もともと定義されていないシステムコール。
        !           159:                return false;
        !           160:        }
        !           161:        putlog(2, "calling system call $%02X", scid);
        !           162:        bool r = (this->*func)();
        !           163: 
        !           164:        if (r == false) {
        !           165:                // 未実装システムコール
        !           166:                putlog(0, "Unimplemented system call $%02X", scid);
        !           167:                RequestExit(0);
        !           168:                return false;
        !           169:        }
        !           170: 
        !           171:        return r;
        !           172: }
        !           173: 
        !           174: // 内部関数
        !           175: 
        !           176: // 仮想マシンの中から終了させる
        !           177: void
        !           178: HumanMI::RequestExit(int code)
        !           179: {
        !           180:        gMPU->Release();
        !           181:        gScheduler->RequestExit();
        !           182: }
        !           183: 
        !           184: // システムコールの実装
        !           185: 
        !           186: bool
        !           187: HumanMI::DOS_EXIT()
        !           188: {
        !           189:        RequestExit(0);
        !           190:        return true;
        !           191: }
        !           192: 
        !           193: bool
        !           194: HumanMI::DOS_GETCHAR()
        !           195: {
        !           196:        int c;
        !           197:        c = getchar();
        !           198:        Result((uint32)(c & 0xff));
        !           199:        return true;
        !           200: }
        !           201: 
        !           202: bool
        !           203: HumanMI::DOS_PUTCHAR()
        !           204: {
        !           205:        uint16 c = Pop16();
        !           206:        putchar(c);
        !           207:        Result(0);
        !           208:        return true;
        !           209: }
        !           210: 
        !           211: bool
        !           212: HumanMI::DOS_PRINT()
        !           213: {
        !           214:        uint32 ptr = Pop32();
        !           215:        putlog(1, "PRINT ptr=%08x", ptr);
        !           216:        for (;;) {
        !           217:                uint64 c = Read8(ptr++);
        !           218:                putlog(1, "c=%d", (int)c);
        !           219:                if ((int64)c == -1) {
        !           220:                        // バスエラー
        !           221:                        // XXX どうすんの
        !           222:                        // たぶんバスエラーハンドラにジャンプしてバスエラーハンドラが
        !           223:                        // プロセス終了する感じ。
        !           224:                        return false;
        !           225:                }
        !           226:                if (c == 0) break;
        !           227:                printf("%c", (int)c);
        !           228:        }
        !           229:        Result(0);
        !           230:        return true;
        !           231: }
        !           232: 
        !           233: // FF40
        !           234: bool
        !           235: HumanMI::DOS_WRITE()
        !           236: {
        !           237:        uint16 fileno = Pop16();
        !           238:        uint32 dataptr = Pop32();
        !           239:        uint32 size = Pop32();
        !           240:        putmsg(1, "WRITE(%d, 0x%08x, 0x%08x)\n", fileno, dataptr, size);
        !           241:        for (int i = 0; i < size; i++) {
        !           242:                putchar(Read8(dataptr++));
        !           243:        }
        !           244:        Result(size);
        !           245:        return true;
        !           246: }
        !           247: 
        !           248: // FF4A
        !           249: bool
        !           250: HumanMI::DOS_SETBLOCK()
        !           251: {
        !           252:        uint32 memptr = Pop32();
        !           253:        uint32 len = Pop32();
        !           254:        putmsg(1, "DOS SETBLOCK(memptr=$%x len=$%x)", memptr, len);
        !           255:        // なにもせずに、できたという
        !           256:        Result(len);
        !           257:        return true;
        !           258: }
        !           259: 
        !           260: bool
        !           261: HumanMI::DOS_EXIT2()
        !           262: {
        !           263:        uint16 data = Pop16();
        !           264:        RequestExit(data);
        !           265:        return true;
        !           266: }
        !           267: 
        !           268: // HumanMD_m680x0
        !           269: 
        !           270: bool
        !           271: HumanMD_m680x0::Init()
        !           272: {
        !           273:        cpu = gMPU680x0->GetCPU();
        !           274:        gMPU680x0->SetFLineCallback(human_m680x0_fline_callback, this);
        !           275:        return true;
        !           276: }
        !           277: 
        !           278: bool
        !           279: HumanMD_m680x0::SysCallEntry()
        !           280: {
        !           281:        if (RegIR == 0xf600) {
        !           282:                return false;
        !           283:        }
        !           284: 
        !           285:        scid = RegIR & 0xff;
        !           286:        sp = RegA(7);
        !           287:        putlog(1, "IR=%04X sp=%08x", RegIR, sp);
        !           288: 
        !           289:        return Dispatch();
        !           290: }
        !           291: 
        !           292: uint64
        !           293: HumanMD_m680x0::Pop16()
        !           294: {
        !           295:        uint64 rv = Read16(sp);
        !           296:        sp += 2;
        !           297:        return rv;
        !           298: }
        !           299: 
        !           300: uint64
        !           301: HumanMD_m680x0::Pop32()
        !           302: {
        !           303:        uint64 rv = Read32(sp);
        !           304:        sp += 4;
        !           305:        return rv;
        !           306: }
        !           307: 
        !           308: uint32
        !           309: HumanMD_m680x0::ReadReg(int rn)
        !           310: {
        !           311:        assert(0 <= rn && rn < 16);
        !           312:        return RegR(rn);
        !           313: }
        !           314: 
        !           315: void
        !           316: HumanMD_m680x0::WriteReg(int rn, uint32 data)
        !           317: {
        !           318:        assert(0 <= rn && rn < 16);
        !           319:        RegR(rn) = data;
        !           320: }
        !           321: 
        !           322: void
        !           323: HumanMD_m680x0::Result(uint32 data)
        !           324: {
        !           325:        WriteReg(0, data);
        !           326: }
        !           327: 
        !           328: // HumanMD_m88xx0
        !           329: 
        !           330: bool
        !           331: HumanMD_m88xx0::Init()
        !           332: {
        !           333:        cpu = gMPU88xx0->GetCPU();
        !           334:        gMPU88xx0->SetFLineCallback(human_m88xx0_fline_callback, this);
        !           335:        return true;
        !           336: }
        !           337: 
        !           338: bool
        !           339: HumanMD_m88xx0::SysCallEntry()
        !           340: {
        !           341:        scid = cpu->opX & 0xff;
        !           342:        rd = m88100opf_D(cpu->opX);
        !           343:        rs = m88100opf_S1(cpu->opX);
        !           344:        return Dispatch();
        !           345: }
        !           346: 
        !           347: uint64
        !           348: HumanMD_m88xx0::Pop16()
        !           349: {
        !           350:        uint64 rv = ReadReg(rs) & 0xffff;
        !           351:        rs++;
        !           352:        return rv;
        !           353: }
        !           354: 
        !           355: uint64
        !           356: HumanMD_m88xx0::Pop32()
        !           357: {
        !           358:        uint64 rv = ReadReg(rs);
        !           359:        rs++;
        !           360:        return rv;
        !           361: }
        !           362: 
        !           363: uint32
        !           364: HumanMD_m88xx0::ReadReg(int rn)
        !           365: {
        !           366:        assert(0 <= rn && rn < 32);
        !           367:        return cpu->r[rn];
        !           368: }
        !           369: 
        !           370: void
        !           371: HumanMD_m88xx0::WriteReg(int rn, uint32 data)
        !           372: {
        !           373:        assert(0 <= rn && rn < 32);
        !           374:        if (rn != 0) {
        !           375:                cpu->r[rn] = data;
        !           376:        }
        !           377: }
        !           378: 
        !           379: void
        !           380: HumanMD_m88xx0::Result(uint32 data)
        !           381: {
        !           382:        WriteReg(rd, data);
        !           383: }
        !           384: 
        !           385: // CPU からのコールバックはグローバル関数宛なので
        !           386: // クラス呼び出しに変換するだけを担当。
        !           387: bool
        !           388: human_m680x0_fline_callback(m68kcpu *cpu, void *arg)
        !           389: {
        !           390:        auto *human = (HumanMD_m680x0 *)arg;
        !           391:        return human->SysCallEntry();
        !           392: }
        !           393: 
        !           394: bool
        !           395: human_m88xx0_fline_callback(m88kcpu *cpu, void *arg)
        !           396: {
        !           397:        auto *human = (HumanMD_m88xx0 *)arg;
        !           398:        return human->SysCallEntry();
        !           399: }
        !           400: 

unix.superglobalmegacorp.com

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