File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / qemusysctlr.cpp
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:06:00 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v027, HEAD
nono 1.7.0

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

//
// QEMU Virtual System Controller
//

// https://www.qemu.org/docs/master/specs/virt-ctlr.html

#include "qemusysctlr.h"
#include "mainbus.h"
#include "power.h"
#include "syncer.h"

// コンストラクタ
QemuSysCtlrDevice::QemuSysCtlrDevice()
	: inherited(OBJ_QEMUSYSCTLR)
{
}

// デストラクタ
QemuSysCtlrDevice::~QemuSysCtlrDevice()
{
}

busdata
QemuSysCtlrDevice::ReadPort(uint32 offset)
{
	busdata data;

	if (offset == 0) {
		// Features (Read Only)
		data = FEATURES;
		putlog(2, "FEATURES -> $%08x", data.Data());
	} else {
		// 他のポートがどうなるのかは仕様に書いてない。
		data.SetBusErr();
		putlog(1, "Read $%08x (BusErr)", GetMainbusDevice()->GetPaddr());
	}

	data |= BusData::Size4;
	return data;
}

busdata
QemuSysCtlrDevice::WritePort(uint32 offset, uint32 data)
{
	busdata r;

	if (offset == 1) {
		// Command (Write Only)
		static const char *cmdname[] = {
			"no-op",
			"reset",
			"halt",
			"panic",
		};
		putlog(1, "Command <- $%08x (%s)", data,
			(data < countof(cmdname) ? cmdname[data] : cmdname[0]));
		switch (data) {
		 default:
		 case 0:	// no-op
			break;

		 case 1:	// reset
			GetPowerDevice()->MakeResetHard();
			break;

		 case 2:	// halt
			GetPowerDevice()->PushPowerButton();
			break;

		 case 3:	// panic
			DoPanic();
			break;
		}
	} else {
		// 他のポートがどうなるのかは仕様に書いてない。
		putlog(1, "Write $%08x <- $%08x (BusErr)",
			GetMainbusDevice()->GetPaddr(), data);
		r.SetBusErr();
	}

	r |= BusData::Size4;
	return r;
}

busdata
QemuSysCtlrDevice::PeekPort(uint32 offset)
{
	switch (offset) {
	 case 0:	return FEATURES;
	 default:
		return BusData::BusErr;
	}
}

// ゲストがパニックしたので、状態を保全して停止。
// 本当はデバッガで止まるとかすればいいんだろうけど。
void
QemuSysCtlrDevice::DoPanic()
{
	// 速度だけは落としておく。
	auto syncer = GetSyncer();
	syncer->NotifyFullSpeed(false);
}

unix.superglobalmegacorp.com

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