|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2022 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // NEWS の I/O 空間担当
9: //
10:
11: // NWS-1750
12: // +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F'0000
13: // e000'0000 |
14: // e010'0000 |
15: // e020'0000 |
16: // e030'0000 |
17: // e040'0000 |
18: // e050'0000 |
19: // e060'0000 |
20: // e070'0000 |
21: // e080'0000 |
22: // e090'0000 |
23: // e0a0'0000 |
24: // e0b0'0000 |
25: // e0c0'0000 | PAR? FDC SIC
26: // e0d0'0000 |KBC SCC RTC LED
27: // e0e0'0000 |MEM DMAC
28: // e0f0'0000 |ETH
29: //
30: // MEM: Lance のメモリ
31:
32: #include "newsio.h"
33: #include "busio.h"
34: #include "config.h"
35: #include "kbc.h"
36: #include "lance.h"
37: #include "mk48t02.h"
38: #include "newsctlr.h"
39: #include "scc.h"
40: #include "subram.h"
41: #include "vm.h"
42:
43: // コンストラクタ
44: NewsIODevice::NewsIODevice()
45: : inherited(OBJ_NEWSIO)
46: {
47: // SIC を無視するオプション(暫定)
48: int ignore_sic = gConfig->Find("xxx-news-sic-ignore").AsInt();
49:
50: NEWDV(KBC, new KBCDevice());
51: NEWDV(RTC, new BusIO_B<MK48T02Device>());
52: NEWDV(SCC, new BusIO_B<SCCDevice>());
53: NEWDV(Lance, new BusIO_W<LanceDevice>());
54: NEWDV(SubRAM, new SubRAMDevice(16));
55: NEWDV(NopIO, new NopIODevice());
56:
57: // まずバスエラーで埋める。
58: // XXX バスエラーが起きるかどうかは知らないが
59: for (int i = 0; i < table.size(); i++) {
60: table[i] = GetBusErrDevice();
61: }
62:
63: // 少ないので手動で置いていく。
64: auto kbc = pKBC.get();
65: auto lance = pLance.get();
66: auto newsctlr = GetNewsCtlrDevice();
67: auto nopio = pNopIO.get();
68: auto rtc = pRTC.get();
69: auto scc = pSCC.get();
70: auto subram = pSubRAM.get();
71:
72: // table[] は $e0c0'0000 以降を 0x10000 (64KB) 単位にしたもの。
73: #define A(addr) (addr - 0xe0c0)
74:
75: // FDC は現状サポートしていないが (それに機種が違うっぽい?)、
76: // NetBSD の locore.s がリセットのためにアクセスしに来るので
77: // NewsCtlr でついでに対処してある。
78: table[A(0xe0c8)] = newsctlr; // FDC
79: if (ignore_sic) {
80: table[A(0xe0cc)] = nopio; // SIC
81: }
82: table[A(0xe0d0)] = kbc;
83: table[A(0xe0d4)] = scc;
84: table[A(0xe0d8)] = rtc;
85: table[A(0xe0dc)] = newsctlr; // LED
86: table[A(0xe0e0)] = subram;
87: if (ignore_sic) {
88: table[A(0xe0e8)] = nopio; // DMAC
89: }
90: table[A(0xe0f0)] = lance;
91: }
92:
93: // デストラクタ
94: NewsIODevice::~NewsIODevice()
95: {
96: }
97:
98: // 初期化
99: bool
100: NewsIODevice::Init()
101: {
102: if (inherited::Init() == false) {
103: return false;
104: }
105:
106: const ConfigItem& olditem = gConfig->Find("xxx-news-sci-ignore");
107: const ConfigItem& newitem = gConfig->Find("xxx-news-sic-ignore");
108:
109: // 古いオプションだけが指定されていればエラー
110: if (olditem.GetFrom() != ConfigItem::FromInitial &&
111: newitem.GetFrom() == ConfigItem::FromInitial)
112: {
113: olditem.Err("The variable name was changed to \"xxx-news-sic-ignore\" "
114: "('sci' to 'sic'). It was a typo :-) "
115: "Please catch up your configuration.");
116: return false;
117: }
118:
119: // 両方指定されていて値が異なればエラー
120: if (olditem.GetFrom() != ConfigItem::FromInitial &&
121: newitem.GetFrom() != ConfigItem::FromInitial &&
122: olditem.AsString() != newitem.AsString())
123: {
124: newitem.Err("Old \"xxx-news-sci-ignore\" is specified and "
125: "has a different value. Please remove old one.");
126: return false;
127: }
128:
129: return true;
130: }
131:
132: // アドレスから該当するデバイスを返す
133: inline IODevice *
134: NewsIODevice::SearchDevice(uint32 addr) const
135: {
136: // アドレスを table のインデックスに変換。ここに来た時点で
137: // $e0'000000 (かそのミラー) の 16MB 内にいることは分かっている。
138: addr &= 0x00ff'ffff;
139: uint idx = (addr - 0x00c0'0000) >> 16;
140: return table[idx];
141: }
142:
143: uint64
144: NewsIODevice::Read8(uint32 addr)
145: {
146: IODevice *d = SearchDevice(addr);
147: return d->Read8(addr);
148: }
149:
150: uint64
151: NewsIODevice::Read16(uint32 addr)
152: {
153: IODevice *d = SearchDevice(addr);
154: return d->Read16(addr);
155: }
156:
157: uint64
158: NewsIODevice::Read32(uint32 addr)
159: {
160: IODevice *d = SearchDevice(addr);
161: return d->Read32(addr);
162: }
163:
164: uint64
165: NewsIODevice::Write8(uint32 addr, uint32 data)
166: {
167: IODevice *d = SearchDevice(addr);
168: return d->Write8(addr, data);
169: }
170:
171: uint64
172: NewsIODevice::Write16(uint32 addr, uint32 data)
173: {
174: IODevice *d = SearchDevice(addr);
175: return d->Write16(addr, data);
176: }
177:
178: uint64
179: NewsIODevice::Write32(uint32 addr, uint32 data)
180: {
181: IODevice *d = SearchDevice(addr);
182: return d->Write32(addr, data);
183: }
184:
185: uint64
186: NewsIODevice::Peek8(uint32 addr)
187: {
188: IODevice *d = SearchDevice(addr);
189: return d->Peek8(addr);
190: }
191:
192: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用)
193: IODevice *
194: NewsIODevice::GetDevice(uint32 addr) const
195: {
196: return SearchDevice(addr);
197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.