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

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

unix.superglobalmegacorp.com

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