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