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