File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / ppi.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:04:28 2026 UTC (3 months ago) by root
Branches: MAIN, Isaki
CVS tags: v002, v001, HEAD
nono 0.0.1

//
// nono
// Copyright (C) 2017 [email protected]
//

#pragma once

#include "device.h"
#include "scheduler.h"

// Intel 82C55 の仕様書にはコントロールポートからの読み出しは明記してある。
// NEC uPD8255 の仕様書にはコントロールポートからの読み出しについての記載が
// ない (禁止とも書いてない)。
class i8255Device
	: public IODevice
{
	typedef IODevice inherited;

 public:
	i8255Device();
	virtual ~i8255Device();

 protected:
	// コントロールポートの読み出し
	uint32 ReadCtrl() const { return ctrl; }
	// コントロールポートへの書き込み
	void WriteCtrl(uint32);
	// PortC への個別書き込み
	virtual void SetPC(int, int);

	// 7  6  5  4  3   2  1  0
	// 1  AM AM AD CHD BM BD CLD
	//    |  |  |  |   |  |  +--- ポートC下位グループの方向。入力なら1
	//    |  |  |  |   |  +------ ポートB の方向。入力なら1
	//    |  |  |  |   +--------- ポートB のモード。
	//    |  |  |  +------------- ポートC上位グループの方向。入力なら1
	//    |  |  +---------------- ポートA の方向。入力なら1
	//    +--+------------------- ポートA のモード。
	uint8 ctrl = 0;			// コントロールポートの値

	static const uint DIR_IN  = 1;
	static const uint DIR_OUT = 0;
	// グループA/B (ポートA/B) のモード
	uint GetGroupAMode() const	{ return (ctrl >> 5) & 3; }
	uint GetGroupBMode() const	{ return (ctrl >> 2) & 1; }
	// ポート A/B/C上位/C下位 の入出力方向
	uint PortADir() const	{ return (ctrl & 0x10) ? DIR_IN : DIR_OUT; }
	uint PortBDir() const	{ return (ctrl & 0x02) ? DIR_IN : DIR_OUT; }
	uint PortCHDir() const	{ return (ctrl & 0x08) ? DIR_IN : DIR_OUT; }
	uint PortCLDir() const	{ return (ctrl & 0x01) ? DIR_IN : DIR_OUT; }
};


class PPIDevice
	: public i8255Device
{
	typedef i8255Device inherited;
 private:
	static const int baseaddr = 0xe9a000;

 public:
	PPIDevice();
	virtual ~PPIDevice();

	virtual uint64 Read8(uint32 addr);
	virtual uint64 Read16(uint32 addr);
	virtual uint64 Write8(uint32 addr, uint32 data);
	virtual uint64 Write16(uint32 addr, uint32 data);
	virtual uint64 Peek8(uint32 addr);
};

class PIO0Device
	: public i8255Device
{
	typedef i8255Device inherited;
 public:
	PIO0Device();
	virtual ~PIO0Device();

	virtual bool Init();
	virtual uint64 Read8(uint32 addr);
	virtual uint64 Write8(uint32 addr, uint32 data);

 private:
	virtual void SetPC(int, int);

	bool dipsw1[8] {};
	bool dipsw2[8] {};
	bool int1rq = false;	// $01 INT1 割り込み要求
	bool int1en = false;	// $04 INT1 割り込み許可
	bool int5rq = false;	// $08 INT5 割り込み要求
	bool int5en = false;	// $10 INT5 割り込み許可
	bool parity = false;	// $40 パリティ有効/無効
	bool xp_reset = false;	// $80 XP リセット
};

class PIO1Device
	: public i8255Device
{
	typedef i8255Device inherited;
 public:
	PIO1Device();
	virtual ~PIO1Device();

	virtual uint64 Read8(uint32 addr);
	virtual uint64 Write8(uint32 addr, uint32 data);

 private:
	virtual void SetPC(int, int);
	void PowerOffCallback(int);

	bool power = false;		// パワーダウン (false で電源オフ指示)
	bool xp_intreq = false;	// XP 割り込み要求。あり(true)なら %0
	Event poffevent {};		// 電源オフイベント
};

unix.superglobalmegacorp.com

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