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

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:        const ConfigItem& olditem = gConfig->Find("xxx-news-sci-ignore");
                    102:        const ConfigItem& newitem = gConfig->Find("xxx-news-sic-ignore");
                    103: 
1.1.1.2   root      104:        // 指定されていれば警告だけ出してスルーする。
                    105:        if (newitem.GetFrom() != ConfigItem::FromInitial) {
                    106:                newitem.Err("obsoleted");
1.1       root      107:        }
1.1.1.2   root      108:        if (olditem.GetFrom() != ConfigItem::FromInitial) {
                    109:                olditem.Err("obsoleted");
1.1       root      110:        }
                    111: 
1.1.1.2   root      112:        // モニタは実行中には変化しないので最初に作っておく。
                    113:        InitMonitor();
                    114: 
1.1       root      115:        return true;
                    116: }
                    117: 
                    118: // アドレスから該当するデバイスを返す
                    119: inline IODevice *
                    120: NewsIODevice::SearchDevice(uint32 addr) const
                    121: {
                    122:        // アドレスを table のインデックスに変換。ここに来た時点で
                    123:        // $e0'000000 (かそのミラー) の 16MB 内にいることは分かっている。
                    124:        addr &= 0x00ff'ffff;
                    125:        uint idx = (addr - 0x00c0'0000) >> 16;
                    126:        return table[idx];
                    127: }
                    128: 
1.1.1.2   root      129: busdata
1.1.1.3   root      130: NewsIODevice::Read(busaddr addr)
1.1       root      131: {
1.1.1.3   root      132:        IODevice *d = SearchDevice(addr.Addr());
                    133:        return d->Read(addr);
1.1       root      134: }
                    135: 
1.1.1.2   root      136: busdata
1.1.1.3   root      137: NewsIODevice::Write(busaddr addr, uint32 data)
1.1       root      138: {
1.1.1.3   root      139:        IODevice *d = SearchDevice(addr.Addr());
                    140:        return d->Write(addr, data);
1.1       root      141: }
                    142: 
1.1.1.2   root      143: busdata
1.1.1.3   root      144: NewsIODevice::Peek1(uint32 addr)
1.1       root      145: {
                    146:        IODevice *d = SearchDevice(addr);
1.1.1.3   root      147:        return d->Peek1(addr);
1.1       root      148: }
                    149: 
1.1.1.2   root      150: bool
1.1.1.3   root      151: NewsIODevice::Poke1(uint32 addr, uint32 data)
1.1.1.2   root      152: {
                    153:        IODevice *d = SearchDevice(addr);
1.1.1.3   root      154:        return d->Poke1(addr, data);
1.1.1.2   root      155: }
                    156: 
                    157: // モニタを初期化。
                    158: void
                    159: NewsIODevice::InitMonitor()
                    160: {
                    161:        TextScreen& screen = src_screen;
                    162:        int y = 0;
                    163: 
                    164:        screen.Clear();
                    165: 
                    166:        // 012345678901234567890
                    167:        // $0000'0000: 1234567
                    168: 
                    169:        // table[] は $e0c0 以降なのでここには何もないが
                    170:        // モニタ上の表をきりのいい範囲にするために埋めておく。
                    171:        auto nop = MainbusBaseDevice::FormatDevName(GetNopIODevice());
                    172:        for (uint32 addr = 0xe000; addr < 0xe0c0; ) {
                    173:                screen.Print(0, y, "$%04x'0000:", addr);
                    174:                for (int j = 0; j < 8; j++) {
                    175:                        const std::string& name = nop.first;
                    176:                        TA attr = nop.second;
                    177:                        screen.Puts(12 + j * 8, y, attr, name.c_str());
                    178:                        addr++;
                    179:                }
                    180:                y++;
                    181:        }
                    182: 
                    183:        int idx = 0;
                    184:        for (int i = 0; i < table.size() / 8; i++) {
                    185:                uint32 addr = 0xe0c0 + idx;
                    186:                screen.Print(0, y, "$%04x'0000:", addr);
                    187:                for (int j = 0; j < 8; j++) {
                    188:                        auto pair = MainbusBaseDevice::FormatDevName(table[idx]);
                    189:                        const std::string& name = pair.first;
                    190:                        TA attr = pair.second;
                    191:                        screen.Print(12 + j * 8, y, attr, "%s", name.c_str());
                    192:                        idx++;
                    193:                }
                    194:                y++;
                    195:        }
                    196: 
                    197:        // 下半分は NewsCtlr で処理。
                    198:        newsctlr->MonitorUpdateNewsCtlr(screen, y);
                    199: }
                    200: 
                    201: void
                    202: NewsIODevice::MonitorUpdate(Monitor *, TextScreen& screen)
1.1       root      203: {
1.1.1.2   root      204:        // pos が表示開始位置(0-)
                    205:        int pos = (int)screen.userdata;
                    206: 
                    207:        // ヘッダは常に描く
                    208:        screen.Clear();
                    209:        for (int i = 0; i < 8; i++) {
                    210:                screen.Print(12 + i * 8, 0, "+$%x'", i);
                    211:        }
                    212: 
                    213:        // 裏バッファからコピーするだけ。
                    214:        screen.CopyRowsFrom(1, screen.GetRow() - 1, src_screen, pos);
1.1       root      215: }

unix.superglobalmegacorp.com

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