|
|
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.1.8 ! root 120: uint32 data;
! 121: data = mem[addr & mask];
! 122: putlog(4, "$%08x.B -> $%02x", addr, data);
! 123: return data;
1.1 root 124: }
125:
126: uint64
127: ROMDevice::Read16(uint32 addr)
128: {
1.1.1.4 root 129: gMPU->AddCycle(wait);
1.1 root 130: uint16 data;
1.1.1.8 ! root 131: data = be16toh(*(uint16 *)&mem[addr & mask]);
! 132: putlog(4, "$%08x.W -> $%04x", addr, data);
! 133: return data;
1.1 root 134: }
135:
136: uint64
137: ROMDevice::Read32(uint32 addr)
138: {
1.1.1.4 root 139: gMPU->AddCycle(wait);
1.1 root 140: uint32 data;
1.1.1.8 ! root 141: data = be32toh(*(uint32 *)&mem[addr & mask]);
! 142: putlog(4, "$%08x.L -> $%08x", addr, data);
! 143: return data;
1.1 root 144: }
145:
146: uint64
147: ROMDevice::Write8(uint32 addr, uint32 data)
148: {
1.1.1.4 root 149: gMPU->AddCycle(wait); // ?
1.1.1.8 ! root 150: putlog(4, "$%08x.B <- $%02x", addr, data);
1.1.1.7 root 151: return write_op;
1.1 root 152: }
153:
154: uint64
155: ROMDevice::Write16(uint32 addr, uint32 data)
156: {
1.1.1.4 root 157: gMPU->AddCycle(wait); // ?
1.1.1.8 ! root 158: putlog(4, "$%08x.W <- $%04x", addr, data);
1.1.1.7 root 159: return write_op;
1.1 root 160: }
161:
162: uint64
163: ROMDevice::Write32(uint32 addr, uint32 data)
164: {
1.1.1.4 root 165: gMPU->AddCycle(wait); // ?
1.1.1.8 ! root 166: putlog(4, "$%08x.L <- $%08x", addr, data);
1.1.1.7 root 167: return write_op;
1.1 root 168: }
169:
170: uint64
171: ROMDevice::Peek8(uint32 addr)
172: {
173: return mem[addr & mask];
174: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.