|
|
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" ! 29: #include "interrupt.h" ! 30: #include "mainapp.h" ! 31: #include "mainram.h" ! 32: #include "newsctlr.h" ! 33: #include "newsio.h" ! 34: #include "prom.h" ! 35: #include "romemu_news.h" ! 36: ! 37: // コンストラクタ ! 38: NewsMainbus::NewsMainbus() ! 39: { ! 40: NEWDV(BusErr, new BusErrDevice()); ! 41: NEWDV(Interrupt, new NewsInterrupt()); ! 42: NEWDV(PROM, new NewsROMEmuDevice()); ! 43: NEWDV(MainRAM, new MainRAMDevice()); ! 44: NEWDV(NopIO, new NopIODevice()); // required by NewsIO ! 45: NEWDV(NewsCtlr, new NewsCtlrDevice()); ! 46: NEWDV(NewsIO, new NewsIODevice()); ! 47: ! 48: // 公式には $c0'000000〜$ff'ffffff となっているが、 ! 49: // たぶん上位2ビットがデコードされてないように見えるので、 ! 50: // ここでは $00'000000〜$3f'ffffff ×4 として扱う。 ! 51: ! 52: // $eX'XXXXXX はバスエラーが起きないらしい。 ! 53: // $fX'XXXXXX はバスエラーが起きるらしい。 ! 54: // それ以上は詳細不明。 ! 55: // とりあえず $eX'XXXXXX だけ NopIO、他はバスエラーにしておく。 ! 56: for (int i = 0; i < 0x40; i++) { ! 57: devtable[i] = pBusErr.get(); ! 58: } ! 59: for (int i = 0x20; i < 0x30; i++) { ! 60: devtable[i] = pNopIO.get(); ! 61: } ! 62: ! 63: // 少ないので手動で置いていく。 ! 64: auto newsio = pNewsIO.get(); ! 65: auto newsctlr = pNewsCtlr.get(); ! 66: auto prom = pPROM.get(); ! 67: #define A(addr) (((addr) >> 24) & 0x3f) ! 68: devtable[A(0xe0'000000)] = newsio; ! 69: devtable[A(0xe1'000000)] = newsctlr; ! 70: devtable[A(0xf8'000000)] = prom; ! 71: ! 72: // 2MB ずつ 30bit のみ。 ! 73: acc.resize(2048 / 4); ! 74: monitor_accstat.SetSize(80, 2 + 32 / 4); ! 75: } ! 76: ! 77: // デストラクタ ! 78: NewsMainbus::~NewsMainbus() ! 79: { ! 80: } ! 81: ! 82: // メインバスの初期化 ! 83: bool ! 84: NewsMainbus::InitMainbus() ! 85: { ! 86: // RAM は容量が確定した後のここで配置。 ! 87: auto mainram = dynamic_cast<MainRAMDevice *>(pMainRAM.get()); ! 88: int ram_size_MB = mainram->GetSizeMB(); ! 89: int i = 0; ! 90: while (ram_size_MB >= 16) { ! 91: // 16MB 単位にとりあえずしとく ! 92: devtable[i++] = mainram; ! 93: ram_size_MB -= 16; ! 94: } ! 95: ! 96: // $40'000000〜、$80'000000〜、$c0'000000〜はミラーっぽい。 ! 97: memcpy(&devtable[0x40], &devtable[0], 0x40 * sizeof(devtable[0])); ! 98: memcpy(&devtable[0x80], &devtable[0], 0x40 * sizeof(devtable[0])); ! 99: memcpy(&devtable[0xc0], &devtable[0], 0x40 * sizeof(devtable[0])); ! 100: ! 101: // アクセス状況用のマップを作成。 ! 102: InitAccStat(); ! 103: ! 104: return true; ! 105: } ! 106: ! 107: // ブートページを切り替える。 ! 108: void ! 109: NewsMainbus::SwitchBootPage(bool isram) ! 110: { ! 111: // まだサポートしていない。 ! 112: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.