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

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

unix.superglobalmegacorp.com

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