File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / bus.cpp
Revision 1.1.1.8 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:05:10 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v016, v015, HEAD
nono 0.3.0

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

//
// 物理バスアクセス?
//

// addr はそれぞれアラインされていること

#include "bus.h"
#include "ram.h"

IODevice *devtable[256];

// RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を
// 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。
// 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを
// 計算する分を回避したい。
int direct_ram_size;

uint64
vm_phys_read_8(uint32 addr)
{
	uint64 data;

	if (addr < direct_ram_size) {
		data = mainram[HLB(addr)];
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		data = dev->Read8(addr);
	}
	return data;
}

uint64
vm_phys_read_16(uint32 addr)
{
	uint64 data;

	if (__predict_false((addr & 1) != 0))
		VMPANIC("unaligned access $%08x", addr);

	if (addr < direct_ram_size) {
		data = *(uint16 *)&mainram[HLW(addr)];
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		data = dev->Read16(addr);
	}
	return data;
}

uint64
vm_phys_read_32(uint32 addr)
{
	uint64 data;

	if (__predict_false((addr & 3) != 0))
		VMPANIC("unaligned access $%08x", addr);

	if (addr < direct_ram_size) {
		data = *(uint32 *)&mainram[addr];
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		data = dev->Read32(addr);
	}
	return data;
}

uint64
vm_phys_write_8(uint32 addr, uint32 data)
{
	if (addr < direct_ram_size) {
		mainram[HLB(addr)] = data;
		return 0;
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		return dev->Write8(addr, data);
	}
}

uint64
vm_phys_write_16(uint32 addr, uint32 data)
{
	if (__predict_false((addr & 1) != 0))
		VMPANIC("unaligned access $%08x", addr);

	if (addr < direct_ram_size) {
		*(uint16 *)&mainram[HLW(addr)] = data;
		return 0;
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		return dev->Write16(addr, data);
	}
}

uint64
vm_phys_write_32(uint32 addr, uint32 data)
{
	if (__predict_false((addr & 3) != 0))
		VMPANIC("unaligned access $%08x", addr);

	if (addr < direct_ram_size) {
		*(uint32 *)&mainram[addr] = data;
		return 0;
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		return dev->Write32(addr, data);
	}
}

uint64
vm_phys_peek_8(uint32 addr)
{
	uint64 data;

	if (addr < direct_ram_size) {
		data = mainram[HLB(addr)];
	} else {
		IODevice *dev = ::devtable[addr >> 24];
		data = dev->Peek8(addr);
	}
	return data;
}

unix.superglobalmegacorp.com

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