File:  [Isaki's NoNo m68k/m88k emulator] / nono / vm / romimg.cpp
Revision 1.1.1.1 (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) 2018 [email protected]
//

#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include "romimg.h"
#include "mainapp.h"

//
// ROM 共通部
//
// ROM はビッグエンディアンのままメモリに置かれるので、
// 必要ならアクセス時に都度変換すること。
//

ROMDevice::ROMDevice()
{
	logname = "rom";

	mask = 0xffffffff;
	fd = -1;
}

ROMDevice::~ROMDevice()
{
	if (file) {
		munmap(file, filesize);
		file = NULL;
	}
	if (fd != 0) {
		close(fd);
		fd = -1;
	}
}

// name の ROM を探してロードする。
// name はパスを含まないファイル名のみ。パスはこちらで探す。
// mem は file をさす。
// 失敗した場合はエラーメッセージを表示して false を返す。
bool
ROMDevice::LoadROM(const char *name, int size)
{
	struct stat st;

	filename = gMainApp.SearchFile(name);
	if (filename.empty()) {
		warnx("%s not found", name);
		return false;
	}

	// オープン
	fd = open(filename.c_str(), O_RDONLY);
	if (fd == -1) {
		warn("ROM \"%s\" open failed", filename.c_str());
		return false;
	}

	// ファイルサイズをチェック。
	// ファイルが短くても mmap はしれっと成功してしまうようだ。
	if (fstat(fd, &st) == -1) {
		warn("ROM \"%s\" fstat failed", filename.c_str());
		close(fd);
		return false;
	}
	if (st.st_size < size) {
		warnx("ROM \"%s\" is too short (filesize is expected %d but %d)",
			filename.c_str(), size, (int)st.st_size);
		close(fd);
		return false;
	}
	if (st.st_size > size) {
		// 大きすぎるほうはワーニングだけでいいか
		warnx("ROM \"%s\" is too large (ignore %d bytes)",
			filename.c_str(), (int)st.st_size - size);
	}

	// mmap
	// ファイルには書き戻さないけど、オンメモリでハックを入れることが
	// できるように MAP_PRIVATE を指定する。
	filesize = size;
	file = (uint8 *)mmap(NULL, filesize, PROT_READ | PROT_WRITE,
		MAP_PRIVATE, fd, 0);
	if (file == MAP_FAILED) {
		warn("ROM \"%s\" mmap failed", filename.c_str());
		close(fd);
		return false;
	}

	mem = file;
	return true;
}

uint64
ROMDevice::Read8(uint32 addr)
{
	return mem[addr & mask];
}

uint64
ROMDevice::Read16(uint32 addr)
{
	uint16 data;
	data = *(uint16 *)&mem[addr & mask];
	return be16toh(data);
}

uint64
ROMDevice::Read32(uint32 addr)
{
	uint32 data;
	data = *(uint32 *)&mem[addr & mask];
	return be32toh(data);
}

uint64
ROMDevice::Write8(uint32 addr, uint32 data)
{
	return (uint64)-1;
}

uint64
ROMDevice::Write16(uint32 addr, uint32 data)
{
	return (uint64)-1;
}

uint64
ROMDevice::Write32(uint32 addr, uint32 data)
{
	return (uint64)-1;
}

uint64
ROMDevice::Peek8(uint32 addr)
{
	return mem[addr & mask];
}

unix.superglobalmegacorp.com

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