|
|
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];
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.