File:  [Isaki's NoNo m68k/m88k emulator] / nono / host / hostdevice.h
Revision 1.1.1.9 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:56 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v027, v026, HEAD
nono 1.6.0

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

//
// ホストデバイス (基本クラス)
//

#pragma once

#include "thread.h"
#include "autofd.h"
#include "kevent.h"
#include "rwlock.h"

using DeviceCallback_t = void (Device::*)(uint32);
#define ToDeviceCallback(f) static_cast<DeviceCallback_t>(f)

class HostDevice : public ThreadDevice
{
	using inherited = ThreadDevice;

 protected:
	static constexpr uint8 PIPE_TX			= 0;	// データ送信通知
	static constexpr uint8 PIPE_RESELECT	= 1;	// ドライバ再選択通知

 public:
	static const int DONE				= 0;	// 処理終了
	static const int DATA_FROM_VM		= 1;	// VM からの着信
	static const int DATA_FROM_OUTER	= 2;	// 外部からの着信
	static const int LISTEN_SOCKET		= 3;	// 待受ソケット着信

 protected:
	HostDevice(Device *parent_, uint objid_, const std::string& portname_);
 public:
	~HostDevice() override;

	bool Create2() override;

	void Terminate() override;

	// 設定ファイルキーのプレフィックス ("hostcomX-" とか) を返す
	std::string GetConfigKey() const;

	// 表示用の親デバイスのポート名 ("SIO(uPD7201) Ch.A" とか) を返す。
	std::string GetPortName() const { return portname; }
	void SetPortName(const std::string& portname_) { portname = portname_; }

	// NetDriver からのディスクリプタの登録
	int AddOuter(int fd);
	int DelOuter(int fd);
	int AddListen(int ls, int action);
	int DelListen(int ls);

	// ドライバの再選択を指示。(他スレッドから呼ばれる)
	bool NotifyReselectDriver() {
		return WritePipe(PIPE_RESELECT);
	}

	void ResetRxCallback();
	void SetRxCallback(DeviceCallback_t func, uint32 arg);
	void SetAcceptCallback(DeviceCallback_t func);

	// 直近のエラーメッセージを返す。
	const std::string& GetErrmsg() const { return errmsg; }

 protected:
	void ThreadRun() override;

	virtual void Dispatch(int udata);

	// ドライバから読み込み。キューに投入したデータ数を返す。
	virtual int Read() = 0;

	// ドライバに書き出し。
	virtual void Write() = 0;

	// ドライバの(再)選択。
	virtual bool SelectDriver(bool startup) = 0;

	bool WritePipe(uint32 data);

	// ログ出力
	void putlogn(const char *fmt, ...) const override __printflike(2, 3);

	// 親デバイス
	Device *parent {};

	// 親デバイスのポート名 (UI 表示用)
	std::string portname {};

	// ドライバ切り替えから保護するため。
	// 使うほうは読み書きに関わらず Read ロック。
	// ドライバの切り替えが Write ロック。
	RWLock driverlock {};

	autofd kq {};

	// VM からの送信用パイプ
	autofd rpipe {};
	autofd wpipe {};

	// 各種通知コールバック
	DeviceCallback_t rx_func {};
	uint32 rx_arg {};
	DeviceCallback_t accept_func {};

	std::string errmsg {};

	// スレッド終了フラグ
	bool exit_requested {};
};

unix.superglobalmegacorp.com

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