|
|
1.1 root 1: // vi:set ts=4:
2:
3: //
4: // nono
5: // Copyright (C) 2024 nono project
6: // Licensed under nono-license.txt
7: //
8:
9: #include "runx.h"
10:
11: int
12: iocscall(pid_t pid, struct reg *reg)
13: {
14: uint32 callno = (RegD(0) & 0xff);
15: DEBUG(2, "iocscall $%02x", callno);
16:
17: // IOCS コールは TRAP 命令なので、ここに来た時点で TRAP 命令実行後。
18: // RegPC の1ワード手前が TRAP #15 のはずで、
19: // そのもう1ワード手前は大抵 moveq.l #nn,d0 だが、違う可能性はある。
20:
21: // TRAP 命令のもう1ワード手前からの2ワードを取得して、
22: // moveq.l #nn,d0; trap #15 の組み合わせならここを IOCS コールの
23: // アドレスとする。
24: // そうでなければ、仕方ないので trap #15 の番地だけを指す。
25: // (前の命令が1ワード命令とは限らない)
26: uint32 pc = RegPC - 4;
27: uint32 inst = readmem4(pc);
28: if ((inst & 0xff00ffff) != 0x70004e4f) {
29: pc += 2;
30: }
31:
32: int have_fpu = 1; // XXX
33:
34: switch (callno) {
1.1.1.2 ! root 35: case 0x80: // _B_INTVCS
! 36: {
! 37: uint32 num = RegD(1);
! 38: uint32 newaddr = RegA(1);
! 39: uint32 oldaddr;
! 40: if (num < 0x100) {
! 41: // 例外ベクタ。
! 42: oldaddr = readmem4(num * 4);
! 43: writemem4(num * 4, newaddr);
! 44: TRACE(pc, "IOCS _B_INTVCS(#$%04x, $%06x) -> $%06x",
! 45: num, newaddr, oldaddr);
! 46: } else {
! 47: // 未対応。
! 48: TRACE(pc, "IOCS _B_INTVCS(#$%04x, $%06x) Not supported",
! 49: num, newaddr);
! 50: }
! 51: break;
! 52: }
! 53:
1.1 root 54: case 0x82: // _B_BPEEK
55: {
56: uint32 addr = RegA(1);
57: uint32 data = readmem1(addr);
58:
59: TRACE(pc, "IOCS _B_BPEEK($%06x) -> $%02x", addr, data);
60: RegD(0) = (RegD(0) & 0xffffff00) | data;
61: RegA(1)++;
62: break;
63: }
64:
65: case 0xac: // _SYS_STAT (ROM1.3)
66: TRACE(pc, "IOCS _SYS_STAT(%u)", RegD(1));
67: switch (RegD(1)) {
68: case 0:
69: // MPU 状態の取得。
70: RegD(0) =
71: (250 << 16) // 25.0MHz
72: | (have_fpu << 15) // FPU
73: | (0 << 14) // MMU
74: | (3 << 0); // MPU Type
75: break;
76: case 1:
77: // キャッシュ状態の取得。
78: RegD(0) = 0;
79: break;
80: case 2:
81: // キャッシュを SRAM の設定値に設定。
82: RegD(0) = 0;
83: break;
84: case 3:
85: // キャッシュの消去。
86: RegD(0) = 0;
87: break;
88: case 4:
89: // キャッシュの設定。
90: RegD(0) = 0;
91: break;
92: default:
93: break;
94: }
95: break;
96:
97: default:
98: warnx("%06x: Unknown IOCS call $%02x", RegPC, callno);
99: break;
100: }
101:
102: return 0;
103: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.