File:  [Isaki's NoNo m68k/m88k emulator] / nono / util / runx / iocscall.cpp
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:36 2026 UTC (2 months, 4 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, v025, v024, v023, v022, HEAD
nono 1.2.0

// vi:set ts=4:

//
// nono
// Copyright (C) 2024 nono project
// Licensed under nono-license.txt
//

#include "runx.h"

int
iocscall(pid_t pid, struct reg *reg)
{
	uint32 callno = (RegD(0) & 0xff);
	DEBUG(2, "iocscall $%02x", callno);

	// IOCS コールは TRAP 命令なので、ここに来た時点で TRAP 命令実行後。
	// RegPC の1ワード手前が TRAP #15 のはずで、
	// そのもう1ワード手前は大抵 moveq.l #nn,d0 だが、違う可能性はある。

	// TRAP 命令のもう1ワード手前からの2ワードを取得して、
	// moveq.l #nn,d0; trap #15 の組み合わせならここを IOCS コールの
	// アドレスとする。
	// そうでなければ、仕方ないので trap #15 の番地だけを指す。
	// (前の命令が1ワード命令とは限らない)
	uint32 pc = RegPC - 4;
	uint32 inst = readmem4(pc);
	if ((inst & 0xff00ffff) != 0x70004e4f) {
		pc += 2;
	}

	int have_fpu = 1;	// XXX

	switch (callno) {
	 case 0x80:	// _B_INTVCS
	 {
		uint32 num = RegD(1);
		uint32 newaddr = RegA(1);
		uint32 oldaddr;
		if (num < 0x100) {
			// 例外ベクタ。
			oldaddr = readmem4(num * 4);
			writemem4(num * 4, newaddr);
			TRACE(pc, "IOCS _B_INTVCS(#$%04x, $%06x) -> $%06x",
				num, newaddr, oldaddr);
		} else {
			// 未対応。
			TRACE(pc, "IOCS _B_INTVCS(#$%04x, $%06x) Not supported",
				num, newaddr);
		}
		break;
	 }

	 case 0x82:	// _B_BPEEK
	 {
		uint32 addr = RegA(1);
		uint32 data = readmem1(addr);

		TRACE(pc, "IOCS _B_BPEEK($%06x) -> $%02x", addr, data);
		RegD(0) = (RegD(0) & 0xffffff00) | data;
		RegA(1)++;
		break;
	 }

	 case 0xac:	// _SYS_STAT (ROM1.3)
		TRACE(pc, "IOCS _SYS_STAT(%u)", RegD(1));
		switch (RegD(1)) {
		 case 0:
			// MPU 状態の取得。
			RegD(0) =
				  (250 << 16)		// 25.0MHz
				| (have_fpu << 15)	// FPU
				| (0 << 14)			// MMU
				| (3 << 0);			// MPU Type
			break;
		 case 1:
			// キャッシュ状態の取得。
			RegD(0) = 0;
			break;
		 case 2:
			// キャッシュを SRAM の設定値に設定。
			RegD(0) = 0;
			break;
		 case 3:
			// キャッシュの消去。
			RegD(0) = 0;
			break;
		 case 4:
			// キャッシュの設定。
			RegD(0) = 0;
			break;
		 default:
			break;
		}
		break;

	 default:
		warnx("%06x: Unknown IOCS call $%02x", RegPC, callno);
		break;
	}

	return 0;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.