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

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

#include "iocon.h"
#include "mpu.h"

std::unique_ptr<IOConDevice> gIOCon;

IOConDevice::IOConDevice()
{
	logname = "iocon";
	devname = "IOCtrler";
	devaddr = baseaddr;
	devlen  = 0x2000;
}

IOConDevice::~IOConDevice()
{
}

inline uint64
IOConDevice::Decoder(uint32 addr) const
{
	// 折り返しは?
	addr -= baseaddr;

	// 偶数アドレスはバスエラー
	if ((addr & 1) == 0)
		return (uint64)-1;

	return addr >> 1;
}

uint64
IOConDevice::Read8(uint32 addr)
{
	switch (Decoder(addr)) {
	 case 0:	// $E9C001 割り込みステータス
		return (fdc_int ? 0x80 : 0)
			|  (fdd_int ? 0x40 : 0)
			|  (prt_int ? 0x20 : 0)
			|  (hdd_int ? 0x10 : 0)
			|  (hdd_en  ? 0x08 : 0)
			|  (fdc_en  ? 0x04 : 0)
			|  (fdd_en  ? 0x02 : 0)
			|  (prt_en  ? 0x01 : 0);
	 case 1:	// $E9C003 割り込みベクタ
		return vector;
		break;
	}
	return (uint64)-1;
}

uint64
IOConDevice::Read16(uint32 addr)
{
	return 0xff00 | Read8(addr + 1);
}

uint64
IOConDevice::Write8(uint32 addr, uint32 data)
{
	switch (Decoder(addr)) {
	 case 0:	// $E9C001 割り込みマスク
		hdd_en = (data & 0x08);
		fdc_en = (data & 0x04);
		fdd_en = (data & 0x02);
		prt_en = (data & 0x01);
		putlog(1, "割り込みマスク設定 HDD=%d FDC=%d FDD=%d PRT=%d",
			hdd_en, fdc_en, fdd_en, prt_en);
		return 0;
	 case 1:	// $E9C003 割り込みベクタ
		vector = data & 0xfc;
		putlog(1, "割り込みベクタ設定 $%02x", vector);
		return 0;
	 default:
		break;
	}
	return (uint64)-1;
}

uint64
IOConDevice::Write16(uint32 addr, uint32 data)
{
	return Write8(addr + 1, data);
}

uint64
IOConDevice::Peek8(uint32 addr)
{
	switch (Decoder(addr)) {
	 case 0:
		return (fdc_int ? 0x80 : 0)
			|  (fdd_int ? 0x40 : 0)
			|  (prt_int ? 0x20 : 0)
			|  (hdd_int ? 0x10 : 0)
			|  (hdd_en  ? 0x08 : 0)
			|  (fdc_en  ? 0x04 : 0)
			|  (fdd_en  ? 0x02 : 0)
			|  (prt_en  ? 0x01 : 0);

	 case 1:
		return vector;

	 default:
		return 0xff;
	}
}

// FDC からの割り込み要求
void
IOConDevice::IntFDC()
{
	fdc_int = true;
	if (fdc_en) {
		putlog(1, "FDC からの割り込み要求");
		gMPU680x0->Interrupt(1, vector + 0);
	} else {
		putlog(2, "FDC からの割り込み要求(マスク)");
	}
}

unix.superglobalmegacorp.com

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