|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2018 [email protected]
4: //
5:
6: #include <fcntl.h>
7: #include <unistd.h>
8: #include <sys/mman.h>
9: #include <sys/stat.h>
10: #include "romimg.h"
11: #include "mainapp.h"
12:
13: //
14: // ROM 共通部
15: //
16: // ROM はビッグエンディアンのままメモリに置かれるので、
17: // 必要ならアクセス時に都度変換すること。
18: //
19:
20: ROMDevice::ROMDevice()
21: {
22: logname = "rom";
23:
24: mask = 0xffffffff;
25: fd = -1;
26: }
27:
28: ROMDevice::~ROMDevice()
29: {
30: if (file) {
31: munmap(file, filesize);
32: file = NULL;
33: }
34: if (fd != 0) {
35: close(fd);
36: fd = -1;
37: }
38: }
39:
40: // name の ROM を探してロードする。
41: // name はパスを含まないファイル名のみ。パスはこちらで探す。
42: // mem は file をさす。
43: // 失敗した場合はエラーメッセージを表示して false を返す。
44: bool
45: ROMDevice::LoadROM(const char *name, int size)
46: {
47: struct stat st;
48:
49: filename = gMainApp.SearchFile(name);
50: if (filename.empty()) {
51: warnx("%s not found", name);
52: return false;
53: }
54:
55: // オープン
56: fd = open(filename.c_str(), O_RDONLY);
57: if (fd == -1) {
58: warn("ROM \"%s\" open failed", filename.c_str());
59: return false;
60: }
61:
62: // ファイルサイズをチェック。
63: // ファイルが短くても mmap はしれっと成功してしまうようだ。
64: if (fstat(fd, &st) == -1) {
65: warn("ROM \"%s\" fstat failed", filename.c_str());
66: close(fd);
67: return false;
68: }
69: if (st.st_size < size) {
70: warnx("ROM \"%s\" is too short (filesize is expected %d but %d)",
71: filename.c_str(), size, (int)st.st_size);
72: close(fd);
73: return false;
74: }
75: if (st.st_size > size) {
76: // 大きすぎるほうはワーニングだけでいいか
77: warnx("ROM \"%s\" is too large (ignore %d bytes)",
78: filename.c_str(), (int)st.st_size - size);
79: }
80:
81: // mmap
82: // ファイルには書き戻さないけど、オンメモリでハックを入れることが
83: // できるように MAP_PRIVATE を指定する。
84: filesize = size;
85: file = (uint8 *)mmap(NULL, filesize, PROT_READ | PROT_WRITE,
86: MAP_PRIVATE, fd, 0);
87: if (file == MAP_FAILED) {
88: warn("ROM \"%s\" mmap failed", filename.c_str());
89: close(fd);
90: return false;
91: }
92:
93: mem = file;
94: return true;
95: }
96:
97: uint64
98: ROMDevice::Read8(uint32 addr)
99: {
100: return mem[addr & mask];
101: }
102:
103: uint64
104: ROMDevice::Read16(uint32 addr)
105: {
106: uint16 data;
107: data = *(uint16 *)&mem[addr & mask];
108: return be16toh(data);
109: }
110:
111: uint64
112: ROMDevice::Read32(uint32 addr)
113: {
114: uint32 data;
115: data = *(uint32 *)&mem[addr & mask];
116: return be32toh(data);
117: }
118:
119: uint64
120: ROMDevice::Write8(uint32 addr, uint32 data)
121: {
122: return (uint64)-1;
123: }
124:
125: uint64
126: ROMDevice::Write16(uint32 addr, uint32 data)
127: {
128: return (uint64)-1;
129: }
130:
131: uint64
132: ROMDevice::Write32(uint32 addr, uint32 data)
133: {
134: return (uint64)-1;
135: }
136:
137: uint64
138: ROMDevice::Peek8(uint32 addr)
139: {
140: return mem[addr & mask];
141: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.