|
|
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.