|
|
1.1 root 1: //
2: // nono
1.1.1.3 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.7 ! root 7: // ROM の共通部分
! 8: //
! 9: // IODevice
! 10: // |
! 11: // | +-----------+
! 12: // +--| ROMDevice | (LoadROM()、ウェイト、マスク等を持つ)
! 13: // | +-----------+
! 14: // | |
! 15: // | +-- PROMDevice (LUNA* の PROM)
! 16: // | +-- IPLROM1Device (X680x0 の IPLROM 後半)
! 17: // | +-- IPLROM2Device (X680x0 の IPLROM 前半)
! 18: // | +-- CGROMDevice (X680x0 の CGROM)
! 19: // | +-- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分)
! 20: // | |
! 21: // | +-- Luna1PROMEmuDevice (LUNA1 の PROM エミュレーション)
! 22: // | +-- Luna88kPROMEmuDevice (LUNA88K の PROM エミュレーション)
! 23: // |
! 24: // +-- PROM0Device (LUNA* のブートページ切り替え用プロキシ)
! 25: // +-- IPLROM0Device (X680x0 のブートページ切り替え用プロキシ)
! 26:
1.1 root 27: #include "rom.h"
1.1.1.7 ! root 28: #include "autofd.h"
1.1.1.3 root 29: #include "mainapp.h"
1.1.1.5 root 30: #include "mpu.h"
1.1.1.7 ! root 31: #include <fcntl.h>
! 32: #include <unistd.h>
! 33: #include <sys/stat.h>
1.1 root 34:
35: //
36: // ROM 共通部
37: //
38:
1.1.1.6 root 39: ROMDevice::ROMDevice(const std::string& objname_)
40: : inherited(objname_)
1.1 root 41: {
42: mask = 0xffffffff;
43: }
44:
45: ROMDevice::~ROMDevice()
46: {
47: }
48:
49: // name の ROM を探してロードする。
50: // name はパスを含まないファイル名のみ。パスはこちらで探す。
51: // 失敗した場合はエラーメッセージを表示して false を返す。
52: bool
53: ROMDevice::LoadROM(const char *name, int size)
54: {
1.1.1.7 ! root 55: struct stat st;
! 56:
! 57: assert(size > 0);
! 58:
! 59: // ファイル名
1.1.1.3 root 60: filename = gMainApp.SearchFile(name);
1.1 root 61: if (filename.empty()) {
1.1.1.2 root 62: warnx("%s not found", name);
1.1 root 63: return false;
64: }
65:
1.1.1.7 ! root 66: // メモリを確保
! 67: imagebuf.reset(new uint8 [size]);
! 68: if ((bool)imagebuf == false) {
! 69: warnx("ROM \"%s\": Cannot allocate memory (%d bytes)",
! 70: filename.c_str(), size);
! 71: return false;
! 72: }
! 73:
1.1 root 74: // オープン
1.1.1.7 ! root 75: autofd fd = open(filename.c_str(), O_RDONLY);
! 76: if (fd < 0) {
! 77: warn("ROM \"%s\"", filename.c_str());
1.1 root 78: return false;
79: }
80:
1.1.1.7 ! root 81: // ファイルサイズを調べる
! 82: if (fstat(fd, &st) < 0) {
! 83: warn("ROM \"%s\" stat failed", filename.c_str());
! 84: return false;
! 85: }
! 86:
! 87: if (st.st_size < size) {
! 88: warnx("ROM \"%s\" is too short (filesize is expected %d but %jd)",
! 89: filename.c_str(), size, (intmax_t)st.st_size);
! 90: return false;
! 91: }
! 92: if (st.st_size > size) {
! 93: // 大きすぎるほうはワーニングだけでいいか
! 94: warnx("%s is too large (ignore %zd bytes)",
! 95: filename.c_str(), (ssize_t)st.st_size - size);
! 96: return false;
! 97: }
! 98:
! 99: // 読み込む
! 100: ssize_t n = read(fd, &imagebuf[0], size);
! 101: if (n < 0) {
! 102: warn("ROM \"%s\" read failed", filename.c_str());
! 103: return false;
! 104: }
! 105: if (n < size) {
! 106: warnx("ROM \"%s\" read too short", filename.c_str());
! 107: return false;
! 108: }
! 109:
! 110: fd.Close();
! 111:
! 112: mem = &imagebuf[0];
1.1 root 113: return true;
114: }
115:
116: uint64
117: ROMDevice::Read8(uint32 addr)
118: {
1.1.1.4 root 119: gMPU->AddCycle(wait);
1.1 root 120: return mem[addr & mask];
121: }
122:
123: uint64
124: ROMDevice::Read16(uint32 addr)
125: {
1.1.1.4 root 126: gMPU->AddCycle(wait);
1.1 root 127: uint16 data;
128: data = *(uint16 *)&mem[addr & mask];
129: return be16toh(data);
130: }
131:
132: uint64
133: ROMDevice::Read32(uint32 addr)
134: {
1.1.1.4 root 135: gMPU->AddCycle(wait);
1.1 root 136: uint32 data;
137: data = *(uint32 *)&mem[addr & mask];
138: return be32toh(data);
139: }
140:
141: uint64
142: ROMDevice::Write8(uint32 addr, uint32 data)
143: {
1.1.1.4 root 144: gMPU->AddCycle(wait); // ?
1.1.1.7 ! root 145: return write_op;
1.1 root 146: }
147:
148: uint64
149: ROMDevice::Write16(uint32 addr, uint32 data)
150: {
1.1.1.4 root 151: gMPU->AddCycle(wait); // ?
1.1.1.7 ! root 152: return write_op;
1.1 root 153: }
154:
155: uint64
156: ROMDevice::Write32(uint32 addr, uint32 data)
157: {
1.1.1.4 root 158: gMPU->AddCycle(wait); // ?
1.1.1.7 ! root 159: return write_op;
1.1 root 160: }
161:
162: uint64
163: ROMDevice::Peek8(uint32 addr)
164: {
165: return mem[addr & mask];
166: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.