Annotation of nono/vm/human_mi.cpp, revision 1.1.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.