|
|
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.