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