|
|
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:
17: bool human_m680x0_fline_callback(m68kcpu *cpu, void *arg);
18: bool human_m88xx0_fline_callback(m88kcpu *cpu, void *arg);
19:
20: HumanMI::HumanMI()
21: : inherited("HumanMI")
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);
146: }
147:
148: HumanMI::~HumanMI()
149: {
150: }
151:
152: bool
153: HumanMI::Dispatch()
154: {
155: if (scid < 0 || scid >= scTable.size()) {
156: // もともと定義されていないシステムコール。
157: return false;
158: }
159: auto func = scTable[scid];
160: if (func == nullptr) {
161: // もともと定義されていないシステムコール。
162: return false;
163: }
164: putlog(2, "calling system call $%02X", scid);
165: bool r = (this->*func)();
166:
167: if (r == false) {
168: // 未実装システムコール
1.1.1.3 ! root 169: putlog(0, "system call $%02X (NOT IMPLEMENTED)", scid);
1.1 root 170: RequestExit(0);
171: return false;
172: }
173:
174: return r;
175: }
176:
177: // 内部関数
178:
179: // 仮想マシンの中から終了させる
180: void
181: HumanMI::RequestExit(int code)
182: {
1.1.1.2 root 183: gScheduler->Terminate();
1.1 root 184: }
185:
186: // システムコールの実装
187:
188: bool
189: HumanMI::DOS_EXIT()
190: {
191: RequestExit(0);
192: return true;
193: }
194:
195: bool
196: HumanMI::DOS_GETCHAR()
197: {
198: int c;
199: c = getchar();
200: Result((uint32)(c & 0xff));
201: return true;
202: }
203:
204: bool
205: HumanMI::DOS_PUTCHAR()
206: {
207: uint16 c = Pop16();
208: putchar(c);
209: Result(0);
210: return true;
211: }
212:
213: bool
214: HumanMI::DOS_PRINT()
215: {
216: uint32 ptr = Pop32();
217: putlog(1, "PRINT ptr=%08x", ptr);
218: for (;;) {
219: uint64 c = Read8(ptr++);
220: putlog(1, "c=%d", (int)c);
221: if ((int64)c == -1) {
222: // バスエラー
223: // XXX どうすんの
224: // たぶんバスエラーハンドラにジャンプしてバスエラーハンドラが
225: // プロセス終了する感じ。
226: return false;
227: }
1.1.1.2 root 228: if (c == 0) {
229: break;
230: }
1.1 root 231: printf("%c", (int)c);
232: }
233: Result(0);
234: return true;
235: }
236:
237: // FF40
238: bool
239: HumanMI::DOS_WRITE()
240: {
241: uint16 fileno = Pop16();
242: uint32 dataptr = Pop32();
243: uint32 size = Pop32();
244: putmsg(1, "WRITE(%d, 0x%08x, 0x%08x)\n", fileno, dataptr, size);
245: for (int i = 0; i < size; i++) {
246: putchar(Read8(dataptr++));
247: }
248: Result(size);
249: return true;
250: }
251:
252: // FF4A
253: bool
254: HumanMI::DOS_SETBLOCK()
255: {
256: uint32 memptr = Pop32();
257: uint32 len = Pop32();
258: putmsg(1, "DOS SETBLOCK(memptr=$%x len=$%x)", memptr, len);
259: // なにもせずに、できたという
260: Result(len);
261: return true;
262: }
263:
264: bool
265: HumanMI::DOS_EXIT2()
266: {
267: uint16 data = Pop16();
268: RequestExit(data);
269: return true;
270: }
271:
272: // HumanMD_m680x0
273:
274: bool
275: HumanMD_m680x0::Init()
276: {
277: cpu = gMPU680x0->GetCPU();
278: gMPU680x0->SetFLineCallback(human_m680x0_fline_callback, this);
279: return true;
280: }
281:
282: bool
283: HumanMD_m680x0::SysCallEntry()
284: {
285: if (RegIR == 0xf600) {
286: return false;
287: }
288:
289: scid = RegIR & 0xff;
290: sp = RegA(7);
291: putlog(1, "IR=%04X sp=%08x", RegIR, sp);
292:
293: return Dispatch();
294: }
295:
296: uint64
297: HumanMD_m680x0::Pop16()
298: {
299: uint64 rv = Read16(sp);
300: sp += 2;
301: return rv;
302: }
303:
304: uint64
305: HumanMD_m680x0::Pop32()
306: {
307: uint64 rv = Read32(sp);
308: sp += 4;
309: return rv;
310: }
311:
312: uint32
313: HumanMD_m680x0::ReadReg(int rn)
314: {
315: assert(0 <= rn && rn < 16);
316: return RegR(rn);
317: }
318:
319: void
320: HumanMD_m680x0::WriteReg(int rn, uint32 data)
321: {
322: assert(0 <= rn && rn < 16);
323: RegR(rn) = data;
324: }
325:
326: void
327: HumanMD_m680x0::Result(uint32 data)
328: {
329: WriteReg(0, data);
330: }
331:
332: // HumanMD_m88xx0
333:
334: bool
335: HumanMD_m88xx0::Init()
336: {
337: cpu = gMPU88xx0->GetCPU();
338: gMPU88xx0->SetFLineCallback(human_m88xx0_fline_callback, this);
339: return true;
340: }
341:
342: bool
343: HumanMD_m88xx0::SysCallEntry()
344: {
345: scid = cpu->opX & 0xff;
346: rd = m88100opf_D(cpu->opX);
347: rs = m88100opf_S1(cpu->opX);
348: return Dispatch();
349: }
350:
351: uint64
352: HumanMD_m88xx0::Pop16()
353: {
354: uint64 rv = ReadReg(rs) & 0xffff;
355: rs++;
356: return rv;
357: }
358:
359: uint64
360: HumanMD_m88xx0::Pop32()
361: {
362: uint64 rv = ReadReg(rs);
363: rs++;
364: return rv;
365: }
366:
367: uint32
368: HumanMD_m88xx0::ReadReg(int rn)
369: {
370: assert(0 <= rn && rn < 32);
371: return cpu->r[rn];
372: }
373:
374: void
375: HumanMD_m88xx0::WriteReg(int rn, uint32 data)
376: {
377: assert(0 <= rn && rn < 32);
378: if (rn != 0) {
379: cpu->r[rn] = data;
380: }
381: }
382:
383: void
384: HumanMD_m88xx0::Result(uint32 data)
385: {
386: WriteReg(rd, data);
387: }
388:
389: // CPU からのコールバックはグローバル関数宛なので
390: // クラス呼び出しに変換するだけを担当。
391: bool
392: human_m680x0_fline_callback(m68kcpu *cpu, void *arg)
393: {
394: auto *human = (HumanMD_m680x0 *)arg;
395: return human->SysCallEntry();
396: }
397:
398: bool
399: human_m88xx0_fline_callback(m88kcpu *cpu, void *arg)
400: {
401: auto *human = (HumanMD_m88xx0 *)arg;
402: return human->SysCallEntry();
403: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.