|
|
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.9 root 44: #include "vm.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.7 root 87: gVM->SwitchBootPageToROM(this);
88: }
89:
90: // Read の共通処理。
91: // アドレスのデコードと RAM への切り替え判定を行う。
92: uint32
93: IPLROM0Device::ReadDecoder(uint32 addr)
94: {
95: // ROM アドレスがアクセスされたら切り替える
96: if (addr >= 0xff0000) {
97: gVM->SwitchBootPageToRAM(this);
98: }
99:
100: // どちらにしてもアクセスは ROM のアドレス
101: return addr | 0xff0000;
1.1.1.5 root 102: }
103:
104: uint64
105: IPLROM0Device::Read8(uint32 addr)
106: {
1.1.1.7 root 107: addr = ReadDecoder(addr);
108: return iplrom1->Read8(addr);
1.1.1.5 root 109: }
110:
111: uint64
112: IPLROM0Device::Read16(uint32 addr)
113: {
1.1.1.7 root 114: addr = ReadDecoder(addr);
115: return iplrom1->Read16(addr);
1.1.1.5 root 116: }
117:
118: uint64
119: IPLROM0Device::Read32(uint32 addr)
120: {
1.1.1.7 root 121: addr = ReadDecoder(addr);
122: return iplrom1->Read32(addr);
1.1.1.5 root 123: }
124:
125: // Write は RAM 領域へも ROM 領域へも発生しないはずなので基底のを使う。
126:
127: uint64
128: IPLROM0Device::Peek8(uint32 addr)
129: {
1.1.1.7 root 130: addr |= 0xff0000;
131: return iplrom1->Peek8(addr);
1.1.1.5 root 132: }
133:
134:
135: //
1.1.1.9 root 136: // IPLROM(1) 0xfe0000..0xffffff 担当
1.1 root 137: //
138:
1.1.1.8 root 139: // コンストラクタ
1.1 root 140: IPLROM1Device::IPLROM1Device()
1.1.1.10! root 141: : inherited(OBJ_IPLROM1)
1.1 root 142: {
1.1.1.7 root 143: // X680x0 では ROM への書き込みはバスエラー
144: write_op = -1;
1.1 root 145: }
146:
1.1.1.8 root 147: // デストラクタ
1.1 root 148: IPLROM1Device::~IPLROM1Device()
149: {
150: }
151:
1.1.1.10! root 152: // 初期化
1.1 root 153: bool
154: IPLROM1Device::Init()
155: {
1.1.1.10! root 156: if (inherited::Init() == false) {
! 157: return false;
! 158: }
! 159:
1.1 root 160: std::string name;
1.1.1.10! root 161: uint devlen = 0x020000;
! 162: mask = devlen - 1;
1.1 root 163:
1.1.1.9 root 164: // ベンチマークモードは先に処理。この辺どうするか。
1.1 root 165: if (gMainApp.benchmark_mode != 0) {
166: name = string_format("BENCH%02d.ROM", gMainApp.benchmark_mode);
1.1.1.9 root 167: return LoadROM(name.c_str(), devlen);
1.1 root 168: }
169:
1.1.1.9 root 170: const ConfigItem& item = gConfig->Find("iplrom1-image");
171: name = item.AsString();
172: if (name.empty()) {
173: // 指定がなければ、内蔵 IPLROM を使う。
174: mem = Builtin::IPLROM30;
175: return true;
1.1 root 176: }
1.1.1.9 root 177:
178: // 外部ファイルが指定されれば、それを使う。
179: return LoadROM(name.c_str(), devlen);
1.1 root 180: }
181:
182:
183: //
1.1.1.9 root 184: // IPLROM(2) 0xfc0000..0xfdffff 担当
1.1 root 185: //
186:
1.1.1.8 root 187: // コンストラクタ
1.1 root 188: IPLROM2Device::IPLROM2Device()
1.1.1.10! root 189: : inherited(OBJ_IPLROM2)
1.1 root 190: {
1.1.1.7 root 191: // X680x0 では ROM への書き込みはバスエラー
192: write_op = -1;
1.1 root 193: }
194:
1.1.1.8 root 195: // デストラクタ
1.1 root 196: IPLROM2Device::~IPLROM2Device()
197: {
198: }
199:
1.1.1.10! root 200: // 初期化
1.1 root 201: bool
202: IPLROM2Device::Init()
203: {
1.1.1.10! root 204: if (inherited::Init() == false) {
! 205: return false;
! 206: }
! 207:
! 208: uint devlen = 0x020000;
! 209: mask = devlen - 1;
! 210:
1.1 root 211: if (gMainApp.benchmark_mode != 0) {
212: return true;
213: }
214:
1.1.1.9 root 215: const ConfigItem& item = gConfig->Find("iplrom2-image");
216: std::string name = item.AsString();
217: if (name.empty()) {
218: printf("iplrom2: not yet\n");
1.1 root 219: return false;
220: }
1.1.1.9 root 221:
222: // 外部ファイルが指定されれば、それを使う。
223: return LoadROM(name.c_str(), devlen);
1.1 root 224: }
225:
226:
227: //
228: // CGROM
229: //
230:
1.1.1.8 root 231: // コンストラクタ
1.1 root 232: CGROMDevice::CGROMDevice()
1.1.1.10! root 233: : inherited(OBJ_CGROM)
1.1 root 234: {
1.1.1.7 root 235: // X680x0 では ROM への書き込みはバスエラー
236: write_op = -1;
1.1 root 237: }
238:
1.1.1.8 root 239: // デストラクタ
1.1 root 240: CGROMDevice::~CGROMDevice()
241: {
242: }
243:
1.1.1.10! root 244: // 初期化
1.1 root 245: bool
246: CGROMDevice::Init()
247: {
1.1.1.10! root 248: if (inherited::Init() == false) {
! 249: return false;
! 250: }
! 251:
! 252: uint devlen = 768 * 1024;
! 253: mask = 1024 * 1024 - 1;
! 254:
1.1.1.9 root 255: const ConfigItem& item = gConfig->Find("cgrom-image");
256: std::string name = item.AsString();
257: if (name.empty()) {
258: // 指定がなければ、内蔵 CGROM を使う。
259: mem = Builtin::CGROM;
260: return true;
261: }
262:
263: // 外部ファイルが指定されれば、それを使う。
264: if (LoadROM(name.c_str(), devlen) == false) {
265: // 指定したファイルが読めなければエラー。
1.1 root 266: return false;
267: }
1.1.1.9 root 268:
269: // X68030 の CGROM には、X68000 のものには収録されていない 6x12 フォント
270: // が収録されている。6x12 フォント以外は(たぶん)同じなのでほとんどの場面
271: // で困ることはないが、それ故に忘れた頃に一部の文字だけ表示されなくて
272: // 「???」ということになりがちなので、6x12 フォントが収録されてなさそう
273: // なら警告を出しておく (処理は続行する)。
274: uint8 val = 0;
275: for (int i = 0; i < 12; i++) {
276: val |= imagebuf[0xbf400 + ('0' * 12) + i];
277: }
278: if (val == 0) {
279: warnx("warning: 6x12 font not found in CGROM30.DAT");
280: }
281:
1.1 root 282: return true;
283: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.