|
|
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.