|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // メインバス (NEWS)
9: //
10:
11: // IODevice
12: // +-- MainbusBaseDevice (InitMainbus() と FC アクセスを持つ)
13: // | +-- MainbusDevice (これがメインバス、システムに1つ)
14: // | | +-- Mainbus24Device (上位8ビットがテーブルで表せるメインバス)
15: // | | | +-- LunaMainbus
16: // | | | | +-- Luna1Mainbus
17: // | | | | +-- Luna88kMainbus
18: // | | | |
19: // | | | | +-------------+
20: // | | | +--| NewsMainbus |
21: // | | | | +-------------+
22: // | | | |
23: // | | | +-- Virt68kMainbus
24: // | | +-- X68kMainbus
25: // | +-- X68kIODevice
26: // +-- XPbusDevice
27:
28: #include "mainbus_news.h"
1.1.1.5 ! root 29: #include "buserr.h"
1.1 root 30: #include "interrupt.h"
31: #include "mainapp.h"
32: #include "mainram.h"
1.1.1.3 root 33: #include "monitor.h"
1.1 root 34: #include "newsctlr.h"
35: #include "newsio.h"
1.1.1.5 ! root 36: #include "nop.h"
1.1 root 37: #include "prom.h"
38: #include "romemu_news.h"
39:
40: // コンストラクタ
41: NewsMainbus::NewsMainbus()
42: {
43: NEWDV(BusErr, new BusErrDevice());
44: NEWDV(Interrupt, new NewsInterrupt());
45: NEWDV(PROM, new NewsROMEmuDevice());
46: NEWDV(MainRAM, new MainRAMDevice());
47: NEWDV(NopIO, new NopIODevice()); // required by NewsIO
48: NEWDV(NewsCtlr, new NewsCtlrDevice());
49: NEWDV(NewsIO, new NewsIODevice());
50:
51: // 公式には $c0'000000〜$ff'ffffff となっているが、
52: // たぶん上位2ビットがデコードされてないように見えるので、
53: // ここでは $00'000000〜$3f'ffffff ×4 として扱う。
54:
55: // $eX'XXXXXX はバスエラーが起きないらしい。
56: // $fX'XXXXXX はバスエラーが起きるらしい。
57: // それ以上は詳細不明。
58: // とりあえず $eX'XXXXXX だけ NopIO、他はバスエラーにしておく。
59: for (int i = 0; i < 0x40; i++) {
60: devtable[i] = pBusErr.get();
61: }
62: for (int i = 0x20; i < 0x30; i++) {
63: devtable[i] = pNopIO.get();
64: }
65:
66: // 少ないので手動で置いていく。
67: auto newsio = pNewsIO.get();
68: auto newsctlr = pNewsCtlr.get();
69: auto prom = pPROM.get();
70: #define A(addr) (((addr) >> 24) & 0x3f)
71: devtable[A(0xe0'000000)] = newsio;
72: devtable[A(0xe1'000000)] = newsctlr;
73: devtable[A(0xf8'000000)] = prom;
74:
1.1.1.2 root 75: // アドレス空間は 0xc000'0000 からの 30bit。
76: accstat_baseaddr = 0xc0;
77: accstat_bitlen = 30;
1.1.1.3 root 78: accstat_monitor->SetSize(80, 2 + 32 / 4);
1.1 root 79: }
80:
81: // デストラクタ
82: NewsMainbus::~NewsMainbus()
83: {
84: }
85:
86: // メインバスの初期化
87: bool
88: NewsMainbus::InitMainbus()
89: {
90: // RAM は容量が確定した後のここで配置。
91: auto mainram = dynamic_cast<MainRAMDevice *>(pMainRAM.get());
1.1.1.4 root 92: uint ram_size_MB = mainram->GetSizeMB();
1.1 root 93: int i = 0;
94: while (ram_size_MB >= 16) {
95: // 16MB 単位にとりあえずしとく
96: devtable[i++] = mainram;
97: ram_size_MB -= 16;
98: }
99:
100: // $40'000000〜、$80'000000〜、$c0'000000〜はミラーっぽい。
101: memcpy(&devtable[0x40], &devtable[0], 0x40 * sizeof(devtable[0]));
102: memcpy(&devtable[0x80], &devtable[0], 0x40 * sizeof(devtable[0]));
103: memcpy(&devtable[0xc0], &devtable[0], 0x40 * sizeof(devtable[0]));
104:
105: // アクセス状況用のマップを作成。
106: InitAccStat();
107:
108: return true;
109: }
110:
111: // ブートページを切り替える。
112: void
113: NewsMainbus::SwitchBootPage(bool isram)
114: {
115: // まだサポートしていない。
116: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.