Annotation of nono/vm/newsio.cpp, revision 1.1.1.7

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"
1.1.1.2   root       37: #include "mainbus.h"
1.1       root       38: #include "mk48t02.h"
1.1.1.4   root       39: #include "monitor.h"
1.1       root       40: #include "newsctlr.h"
1.1.1.6   root       41: #include "nop.h"
1.1       root       42: #include "scc.h"
                     43: #include "subram.h"
                     44: #include "vm.h"
                     45: 
                     46: // コンストラクタ
                     47: NewsIODevice::NewsIODevice()
                     48:        : inherited(OBJ_NEWSIO)
                     49: {
1.1.1.3   root       50:        NEWDV(KBC, new BusIO_B<KBCDevice>());
1.1       root       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: 
1.1.1.2   root       56:        // まず NopIO で埋める。
                     57:        // XXX 全域かどうかは分からないが
                     58:        auto nopio = GetNopIODevice();
1.1       root       59:        for (int i = 0; i < table.size(); i++) {
1.1.1.2   root       60:                table[i] = nopio;
1.1       root       61:        }
                     62: 
                     63:        // 少ないので手動で置いていく。
1.1.1.2   root       64:        newsctlr = GetNewsCtlrDevice();
1.1       root       65:        auto kbc = pKBC.get();
                     66:        auto lance = pLance.get();
                     67:        auto rtc = pRTC.get();
                     68:        auto scc = pSCC.get();
                     69:        auto subram = pSubRAM.get();
                     70: 
                     71:        // table[] は $e0c0'0000 以降を 0x10000 (64KB) 単位にしたもの。
                     72: #define A(addr)        (addr - 0xe0c0)
                     73: 
                     74:        // FDC は現状サポートしていないが (それに機種が違うっぽい?)、
                     75:        // NetBSD の locore.s がリセットのためにアクセスしに来るので
                     76:        // NewsCtlr でついでに対処してある。
                     77:        table[A(0xe0c8)] = newsctlr;    // FDC
                     78:        table[A(0xe0d0)] = kbc;
                     79:        table[A(0xe0d4)] = scc;
                     80:        table[A(0xe0d8)] = rtc;
                     81:        table[A(0xe0dc)] = newsctlr;    // LED
                     82:        table[A(0xe0e0)] = subram;
                     83:        table[A(0xe0f0)] = lance;
1.1.1.2   root       84: 
                     85:        src_screen.Init(75, 64, TextScreen::Ring);
                     86: 
1.1.1.4   root       87:        monitor = gMonitorManager->Regist(ID_SUBWIN_NEWSIO, this);
1.1.1.7 ! root       88:        monitor->SetCallback(&NewsIODevice::MonitorScreen);
1.1.1.4   root       89:        monitor->SetSize(src_screen.GetCol(), 1 + 32);
                     90:        monitor->SetMaxHeight(1 + 64);
1.1       root       91: }
                     92: 
                     93: // デストラクタ
                     94: NewsIODevice::~NewsIODevice()
                     95: {
                     96: }
                     97: 
                     98: // 初期化
                     99: bool
                    100: NewsIODevice::Init()
                    101: {
                    102:        const ConfigItem& olditem = gConfig->Find("xxx-news-sci-ignore");
                    103:        const ConfigItem& newitem = gConfig->Find("xxx-news-sic-ignore");
                    104: 
1.1.1.2   root      105:        // 指定されていれば警告だけ出してスルーする。
                    106:        if (newitem.GetFrom() != ConfigItem::FromInitial) {
                    107:                newitem.Err("obsoleted");
1.1       root      108:        }
1.1.1.2   root      109:        if (olditem.GetFrom() != ConfigItem::FromInitial) {
                    110:                olditem.Err("obsoleted");
1.1       root      111:        }
                    112: 
1.1.1.2   root      113:        // モニタは実行中には変化しないので最初に作っておく。
                    114:        InitMonitor();
                    115: 
1.1       root      116:        return true;
                    117: }
                    118: 
                    119: // アドレスから該当するデバイスを返す
                    120: inline IODevice *
                    121: NewsIODevice::SearchDevice(uint32 addr) const
                    122: {
                    123:        // アドレスを table のインデックスに変換。ここに来た時点で
                    124:        // $e0'000000 (かそのミラー) の 16MB 内にいることは分かっている。
                    125:        addr &= 0x00ff'ffff;
                    126:        uint idx = (addr - 0x00c0'0000) >> 16;
                    127:        return table[idx];
                    128: }
                    129: 
1.1.1.2   root      130: busdata
1.1.1.3   root      131: NewsIODevice::Read(busaddr addr)
1.1       root      132: {
1.1.1.3   root      133:        IODevice *d = SearchDevice(addr.Addr());
                    134:        return d->Read(addr);
1.1       root      135: }
                    136: 
1.1.1.2   root      137: busdata
1.1.1.3   root      138: NewsIODevice::Write(busaddr addr, uint32 data)
1.1       root      139: {
1.1.1.3   root      140:        IODevice *d = SearchDevice(addr.Addr());
                    141:        return d->Write(addr, data);
1.1       root      142: }
                    143: 
1.1.1.2   root      144: busdata
1.1.1.3   root      145: NewsIODevice::Peek1(uint32 addr)
1.1       root      146: {
                    147:        IODevice *d = SearchDevice(addr);
1.1.1.3   root      148:        return d->Peek1(addr);
1.1       root      149: }
                    150: 
1.1.1.2   root      151: bool
1.1.1.3   root      152: NewsIODevice::Poke1(uint32 addr, uint32 data)
1.1.1.2   root      153: {
                    154:        IODevice *d = SearchDevice(addr);
1.1.1.3   root      155:        return d->Poke1(addr, data);
1.1.1.2   root      156: }
                    157: 
                    158: // モニタを初期化。
                    159: void
                    160: NewsIODevice::InitMonitor()
                    161: {
                    162:        TextScreen& screen = src_screen;
                    163:        int y = 0;
                    164: 
                    165:        screen.Clear();
                    166: 
                    167:        // 012345678901234567890
                    168:        // $0000'0000: 1234567
                    169: 
                    170:        // table[] は $e0c0 以降なのでここには何もないが
                    171:        // モニタ上の表をきりのいい範囲にするために埋めておく。
                    172:        auto nop = MainbusBaseDevice::FormatDevName(GetNopIODevice());
                    173:        for (uint32 addr = 0xe000; addr < 0xe0c0; ) {
                    174:                screen.Print(0, y, "$%04x'0000:", addr);
                    175:                for (int j = 0; j < 8; j++) {
                    176:                        const std::string& name = nop.first;
                    177:                        TA attr = nop.second;
                    178:                        screen.Puts(12 + j * 8, y, attr, name.c_str());
                    179:                        addr++;
                    180:                }
                    181:                y++;
                    182:        }
                    183: 
                    184:        int idx = 0;
                    185:        for (int i = 0; i < table.size() / 8; i++) {
                    186:                uint32 addr = 0xe0c0 + idx;
                    187:                screen.Print(0, y, "$%04x'0000:", addr);
                    188:                for (int j = 0; j < 8; j++) {
                    189:                        auto pair = MainbusBaseDevice::FormatDevName(table[idx]);
                    190:                        const std::string& name = pair.first;
                    191:                        TA attr = pair.second;
                    192:                        screen.Print(12 + j * 8, y, attr, "%s", name.c_str());
                    193:                        idx++;
                    194:                }
                    195:                y++;
                    196:        }
                    197: 
                    198:        // 下半分は NewsCtlr で処理。
1.1.1.7 ! root      199:        newsctlr->MonitorScreenNewsCtlr(screen, y);
1.1.1.2   root      200: }
                    201: 
                    202: void
1.1.1.7 ! root      203: NewsIODevice::MonitorScreen(Monitor *, TextScreen& screen)
1.1       root      204: {
1.1.1.2   root      205:        // pos が表示開始位置(0-)
                    206:        int pos = (int)screen.userdata;
                    207: 
                    208:        // ヘッダは常に描く
                    209:        screen.Clear();
                    210:        for (int i = 0; i < 8; i++) {
                    211:                screen.Print(12 + i * 8, 0, "+$%x'", i);
                    212:        }
                    213: 
                    214:        // 裏バッファからコピーするだけ。
                    215:        screen.CopyRowsFrom(1, screen.GetRow() - 1, src_screen, pos);
1.1       root      216: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.