|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.