|
|
1.1 root 1: //
2: // nono
1.1.1.2 root 3: // Copyright (C) 2020 nono project
4: // Licensed under nono-license.txt
1.1 root 5: //
6:
1.1.1.8 root 7: //
1.1.1.7 root 8: // X680x0 の各種 ROM
9: //
1.1.1.8 root 10:
1.1.1.7 root 11: // IODevice
12: // |
13: // +-- ROMDevice (LoadROM()、ウェイト、マスク等を持つ)
14: // | |
15: // | +-- PROMDevice (LUNA* の PROM)
16: // | |
17: // | | +---------------+
18: // | +--| IPLROM1Device | (X680x0 の IPLROM 後半)
19: // | | +---------------+
20: // | |
21: // | | +---------------+
22: // | +--| IPLROM2Device | (X680x0 の IPLROM 前半)
23: // | | +---------------+
24: // | |
25: // | | +-------------+
26: // | +--| CGROMDevice | (X680x0 の CGROM)
27: // | | +-------------+
28: // | |
29: // | +-- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分)
30: // | |
1.1.1.10 root 31: // | +-- Luna1PROMEmuDevice (LUNA-I の PROM エミュレーション)
32: // | +-- Luna88kPROMEmuDevice (LUNA-88K の PROM エミュレーション)
1.1.1.7 root 33: // |
34: // +-- PROM0Device (LUNA* のブートページ切り替え用プロキシ)
35: // |
36: // | +---------------+
37: // +--| IPLROM0Device | (X680x0 のブートページ切り替え用プロキシ)
38: // +---------------+
39:
1.1 root 40: #include "romimg_x68k.h"
1.1.1.9 root 41: #include "builtinrom.h"
42: #include "config.h"
1.1 root 43: #include "mainapp.h"
1.1.1.11! root 44: #include "mainbus.h"
1.1 root 45:
46: //
1.1.1.8 root 47: // IPLROM0
48: //
1.1.1.5 root 49: // IPLROM0 は IPLROM(1) のブートページ担当。
50: // これ自身はメモリ領域を持たず IPLROM1 へのプロキシとして動作する。
51: //
52: // X680x0 のブートページは $000000..$00ffff の 64KB で、
53: // ここへのアクセスは $ff0000..$ffffff (IPLROM1 の後半 64KB) が見える。
54: // ROM へアクセスがあればブートページを RAM に切り替える。
55: // そのため、RAM 側も ROM 側もこいつが応対する必要がある。
56:
1.1.1.8 root 57: // コンストラクタ
1.1.1.5 root 58: IPLROM0Device::IPLROM0Device()
1.1.1.10 root 59: : inherited(OBJ_IPLROM_BOOT)
1.1.1.5 root 60: {
1.1.1.10 root 61: // 通常ここからログを出すことはない
1.1.1.6 root 62: ClearAlias();
1.1.1.5 root 63: }
64:
1.1.1.8 root 65: // デストラクタ
1.1.1.5 root 66: IPLROM0Device::~IPLROM0Device()
67: {
68: }
69:
1.1.1.10 root 70: // 初期化
1.1.1.5 root 71: bool
72: IPLROM0Device::Init()
73: {
1.1.1.10 root 74: if (inherited::Init() == false) {
75: return false;
76: }
77:
78: iplrom1 = GetIPLROM1Device();
79:
1.1.1.5 root 80: return true;
81: }
82:
1.1.1.8 root 83: // リセット
1.1.1.5 root 84: void
1.1.1.8 root 85: IPLROM0Device::ResetHard(bool poweron)
1.1.1.5 root 86: {
1.1.1.11! root 87: auto mainbus = GetMainbusDevice();
! 88: mainbus->SwitchBootPageToROM();
1.1.1.7 root 89: }
90:
91: // Read の共通処理。
92: // アドレスのデコードと RAM への切り替え判定を行う。
93: uint32
94: IPLROM0Device::ReadDecoder(uint32 addr)
95: {
96: // ROM アドレスがアクセスされたら切り替える
97: if (addr >= 0xff0000) {
1.1.1.11! root 98: auto mainbus = GetMainbusDevice();
! 99: mainbus->SwitchBootPageToRAM();
1.1.1.7 root 100: }
101:
102: // どちらにしてもアクセスは ROM のアドレス
103: return addr | 0xff0000;
1.1.1.5 root 104: }
105:
1.1.1.11! root 106: busdata
1.1.1.5 root 107: IPLROM0Device::Read8(uint32 addr)
108: {
1.1.1.7 root 109: addr = ReadDecoder(addr);
110: return iplrom1->Read8(addr);
1.1.1.5 root 111: }
112:
1.1.1.11! root 113: busdata
1.1.1.5 root 114: IPLROM0Device::Read16(uint32 addr)
115: {
1.1.1.7 root 116: addr = ReadDecoder(addr);
117: return iplrom1->Read16(addr);
1.1.1.5 root 118: }
119:
1.1.1.11! root 120: busdata
1.1.1.5 root 121: IPLROM0Device::Read32(uint32 addr)
122: {
1.1.1.7 root 123: addr = ReadDecoder(addr);
124: return iplrom1->Read32(addr);
1.1.1.5 root 125: }
126:
127: // Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。
128:
1.1.1.11! root 129: busdata
1.1.1.5 root 130: IPLROM0Device::Peek8(uint32 addr)
131: {
1.1.1.7 root 132: addr |= 0xff0000;
133: return iplrom1->Peek8(addr);
1.1.1.5 root 134: }
135:
136:
137: //
1.1.1.9 root 138: // IPLROM(1) 0xfe0000..0xffffff 担当
1.1 root 139: //
140:
1.1.1.8 root 141: // コンストラクタ
1.1 root 142: IPLROM1Device::IPLROM1Device()
1.1.1.10 root 143: : inherited(OBJ_IPLROM1)
1.1 root 144: {
1.1.1.7 root 145: // X680x0 では ROM への書き込みはバスエラー
146: write_op = -1;
1.1 root 147: }
148:
1.1.1.8 root 149: // デストラクタ
1.1 root 150: IPLROM1Device::~IPLROM1Device()
151: {
152: }
153:
1.1.1.10 root 154: // 初期化
1.1 root 155: bool
156: IPLROM1Device::Init()
157: {
1.1.1.10 root 158: if (inherited::Init() == false) {
159: return false;
160: }
161:
1.1 root 162: std::string name;
1.1.1.10 root 163: uint devlen = 0x020000;
164: mask = devlen - 1;
1.1 root 165:
1.1.1.9 root 166: // ベンチマークモードは先に処理。この辺どうするか。
1.1 root 167: if (gMainApp.benchmark_mode != 0) {
168: name = string_format("BENCH%02d.ROM", gMainApp.benchmark_mode);
1.1.1.9 root 169: return LoadROM(name.c_str(), devlen);
1.1 root 170: }
171:
1.1.1.9 root 172: const ConfigItem& item = gConfig->Find("iplrom1-image");
173: name = item.AsString();
174: if (name.empty()) {
175: // 指定がなければ、内蔵 IPLROM を使う。
176: mem = Builtin::IPLROM30;
177: return true;
1.1 root 178: }
1.1.1.9 root 179:
180: // 外部ファイルが指定されれば、それを使う。
181: return LoadROM(name.c_str(), devlen);
1.1 root 182: }
183:
184:
185: //
1.1.1.9 root 186: // IPLROM(2) 0xfc0000..0xfdffff 担当
1.1 root 187: //
188:
1.1.1.8 root 189: // コンストラクタ
1.1 root 190: IPLROM2Device::IPLROM2Device()
1.1.1.10 root 191: : inherited(OBJ_IPLROM2)
1.1 root 192: {
1.1.1.7 root 193: // X680x0 では ROM への書き込みはバスエラー
194: write_op = -1;
1.1 root 195: }
196:
1.1.1.8 root 197: // デストラクタ
1.1 root 198: IPLROM2Device::~IPLROM2Device()
199: {
200: }
201:
1.1.1.10 root 202: // 初期化
1.1 root 203: bool
204: IPLROM2Device::Init()
205: {
1.1.1.10 root 206: if (inherited::Init() == false) {
207: return false;
208: }
209:
210: uint devlen = 0x020000;
211: mask = devlen - 1;
212:
1.1 root 213: if (gMainApp.benchmark_mode != 0) {
214: return true;
215: }
216:
1.1.1.9 root 217: const ConfigItem& item = gConfig->Find("iplrom2-image");
218: std::string name = item.AsString();
219: if (name.empty()) {
220: printf("iplrom2: not yet\n");
1.1 root 221: return false;
222: }
1.1.1.9 root 223:
224: // 外部ファイルが指定されれば、それを使う。
225: return LoadROM(name.c_str(), devlen);
1.1 root 226: }
227:
228:
229: //
230: // CGROM
231: //
232:
1.1.1.8 root 233: // コンストラクタ
1.1 root 234: CGROMDevice::CGROMDevice()
1.1.1.10 root 235: : inherited(OBJ_CGROM)
1.1 root 236: {
1.1.1.7 root 237: // X680x0 では ROM への書き込みはバスエラー
238: write_op = -1;
1.1 root 239: }
240:
1.1.1.8 root 241: // デストラクタ
1.1 root 242: CGROMDevice::~CGROMDevice()
243: {
244: }
245:
1.1.1.10 root 246: // 初期化
1.1 root 247: bool
248: CGROMDevice::Init()
249: {
1.1.1.10 root 250: if (inherited::Init() == false) {
251: return false;
252: }
253:
254: uint devlen = 768 * 1024;
255: mask = 1024 * 1024 - 1;
256:
1.1.1.9 root 257: const ConfigItem& item = gConfig->Find("cgrom-image");
258: std::string name = item.AsString();
259: if (name.empty()) {
260: // 指定がなければ、内蔵 CGROM を使う。
261: mem = Builtin::CGROM;
262: return true;
263: }
264:
265: // 外部ファイルが指定されれば、それを使う。
266: if (LoadROM(name.c_str(), devlen) == false) {
267: // 指定したファイルが読めなければエラー。
1.1 root 268: return false;
269: }
1.1.1.9 root 270:
271: // X68030 の CGROM には、X68000 のものには収録されていない 6x12 フォント
272: // が収録されている。6x12 フォント以外は(たぶん)同じなのでほとんどの場面
273: // で困ることはないが、それ故に忘れた頃に一部の文字だけ表示されなくて
274: // 「???」ということになりがちなので、6x12 フォントが収録されてなさそう
275: // なら警告を出しておく (処理は続行する)。
276: uint8 val = 0;
277: for (int i = 0; i < 12; i++) {
278: val |= imagebuf[0xbf400 + ('0' * 12) + i];
279: }
280: if (val == 0) {
281: warnx("warning: 6x12 font not found in CGROM30.DAT");
282: }
283:
1.1 root 284: return true;
285: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.