Annotation of nono/vm/mainbus.cpp, revision 1.1.1.2

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // メインバス
                      9: //
                     10: 
                     11: #include "mainbus.h"
                     12: #include "mainram.h"
                     13: 
                     14: // コンストラクタ
                     15: MainbusDevice::MainbusDevice()
                     16:        : inherited(OBJ_MAINBUS)
                     17: {
1.1.1.2 ! root       18:        monitor.func = ToMonitorCallback(&MainbusDevice::MonitorUpdate);
        !            19:        monitor.SetSize(75, 33);
        !            20:        monitor.Regist(ID_MONITOR_MAINBUS);
1.1       root       21: }
                     22: 
                     23: // デストラクタ
                     24: MainbusDevice::~MainbusDevice()
                     25: {
                     26: }
                     27: 
                     28: uint64
                     29: MainbusDevice::Read8(uint32 addr)
                     30: {
                     31:        uint64 data;
                     32: 
                     33:        if (addr < direct_ram_size) {
                     34:                data = MainRAMDevice::mainram[HLB(addr)];
                     35:        } else {
                     36:                IODevice *dev = devtable[addr >> 24];
                     37:                data = dev->Read8(addr);
                     38:        }
                     39:        return data;
                     40: }
                     41: 
                     42: uint64
                     43: MainbusDevice::Read16(uint32 addr)
                     44: {
                     45:        uint64 data;
                     46: 
                     47:        if (__predict_false((addr & 1) != 0))
                     48:                VMPANIC("unaligned access $%08x", addr);
                     49: 
                     50:        if (addr < direct_ram_size) {
                     51:                data = *(uint16 *)&MainRAMDevice::mainram[HLW(addr)];
                     52:        } else {
                     53:                IODevice *dev = devtable[addr >> 24];
                     54:                data = dev->Read16(addr);
                     55:        }
                     56:        return data;
                     57: }
                     58: 
                     59: uint64
                     60: MainbusDevice::Read32(uint32 addr)
                     61: {
                     62:        uint64 data;
                     63: 
                     64:        if (__predict_false((addr & 3) != 0))
                     65:                VMPANIC("unaligned access $%08x", addr);
                     66: 
                     67:        if (addr < direct_ram_size) {
                     68:                data = *(uint32 *)&MainRAMDevice::mainram[addr];
                     69:        } else {
                     70:                IODevice *dev = devtable[addr >> 24];
                     71:                data = dev->Read32(addr);
                     72:        }
                     73:        return data;
                     74: }
                     75: 
                     76: uint64
                     77: MainbusDevice::Write8(uint32 addr, uint32 data)
                     78: {
                     79:        if (addr < direct_ram_size) {
                     80:                MainRAMDevice::mainram[HLB(addr)] = data;
                     81:                return 0;
                     82:        } else {
                     83:                IODevice *dev = devtable[addr >> 24];
                     84:                return dev->Write8(addr, data);
                     85:        }
                     86: }
                     87: 
                     88: uint64
                     89: MainbusDevice::Write16(uint32 addr, uint32 data)
                     90: {
                     91:        if (__predict_false((addr & 1) != 0))
                     92:                VMPANIC("unaligned access $%08x", addr);
                     93: 
                     94:        if (addr < direct_ram_size) {
                     95:                *(uint16 *)&MainRAMDevice::mainram[HLW(addr)] = data;
                     96:                return 0;
                     97:        } else {
                     98:                IODevice *dev = devtable[addr >> 24];
                     99:                return dev->Write16(addr, data);
                    100:        }
                    101: }
                    102: 
                    103: uint64
                    104: MainbusDevice::Write32(uint32 addr, uint32 data)
                    105: {
                    106:        if (__predict_false((addr & 3) != 0))
                    107:                VMPANIC("unaligned access $%08x", addr);
                    108: 
                    109:        if (addr < direct_ram_size) {
                    110:                *(uint32 *)&MainRAMDevice::mainram[addr] = data;
                    111:                return 0;
                    112:        } else {
                    113:                IODevice *dev = devtable[addr >> 24];
                    114:                return dev->Write32(addr, data);
                    115:        }
                    116: }
                    117: 
                    118: uint64
                    119: MainbusDevice::Peek8(uint32 addr)
                    120: {
                    121:        uint64 data;
                    122: 
                    123:        if (addr < direct_ram_size) {
                    124:                data = MainRAMDevice::mainram[HLB(addr)];
                    125:        } else {
                    126:                IODevice *dev = devtable[addr >> 24];
                    127:                data = dev->Peek8(addr);
                    128:        }
                    129:        return data;
                    130: }
                    131: 
                    132: // これだけオーバーライドではないので注意。
                    133: uint64
                    134: MainbusDevice::Peek32(uint32 addr)
                    135: {
                    136:        uint64 data;
                    137: 
                    138:        if (__predict_false((addr & 3) != 0))
                    139:                VMPANIC("unaligned access $%08x", addr);
                    140: 
                    141:        if (addr < direct_ram_size) {
                    142:                data  = *(uint32 *)&MainRAMDevice::mainram[addr];
                    143:        } else {
                    144:                IODevice *dev = devtable[addr >> 24];
                    145:                data  = dev->Peek8(addr++) << 24;
                    146:                data |= dev->Peek8(addr++) << 16;
                    147:                data |= dev->Peek8(addr++) << 8;
                    148:                data |= dev->Peek8(addr);
                    149:        }
                    150:        return data;
                    151: }
                    152: 
                    153: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用)
                    154: IODevice *
                    155: MainbusDevice::GetDevice(uint32 addr) const
                    156: {
                    157:        return devtable[addr >> 24];
                    158: }
                    159: 
                    160: // デバイスをセットする。すでにあれば更新する。
                    161: // idx は devtable[] のインデックス (16MB 単位)。
                    162: /*static*/ void
                    163: MainbusDevice::SetDevice(int idx, IODevice *dev)
                    164: {
                    165:        assert(idx < devtable.size());
                    166: 
                    167:        devtable[idx] = dev;
                    168: }
                    169: 
                    170: // デバイステーブルの src から len 個を dst にコピーする。(ミラーを作る)
                    171: /*static*/ void
                    172: MainbusDevice::CopyDevtable(int dst, int src, int len)
                    173: {
                    174:        memcpy(&devtable[dst], &devtable[src], sizeof(devtable[0]) * len);
                    175: }
                    176: 
1.1.1.2 ! root      177: void
        !           178: MainbusDevice::MonitorUpdate(Monitor *, TextScreen& screen)
        !           179: {
        !           180:        screen.Clear();
        !           181: 
        !           182:        // 012345678901234567890
        !           183:        // $0000'0000: 1234567
        !           184: 
        !           185:        for (int i = 0; i < 8; i++) {
        !           186:                screen.Print(12 + i * 8, 0, "+$0%x", i);
        !           187:        }
        !           188: 
        !           189:        int idx = 0;
        !           190:        for (int i = 0; i < devtable.size() / 8; i++) {
        !           191:                screen.Print(0, i + 1, "$%02x00'0000:", idx);
        !           192:                for (int j = 0; j < 8; j++) {
        !           193:                        auto pair = FormatDevName(devtable[idx]);
        !           194:                        const std::string& name = pair.first;
        !           195:                        TA attr = pair.second;
        !           196:                        screen.Print(12 + j * 8, i + 1, attr, "%s", name.c_str());
        !           197:                        idx++;
        !           198:                }
        !           199:        }
        !           200: }
        !           201: 
        !           202: // モニタ表示用にデバイス名を整形。
        !           203: // 7文字に切り詰めるのと、括弧があれば取り除いて Disable 色にする。
        !           204: /*static*/ std::pair<std::string, TA>
        !           205: MainbusDevice::FormatDevName(const Device *dev)
        !           206: {
        !           207:        std::string name = dev->GetName();
        !           208:        TA attr;
        !           209: 
        !           210:        if (name[0] == '(') {
        !           211:                // 括弧付きなら、括弧を取り除いて Disable 色で表示
        !           212:                int len = std::min(7, (int)name.size() - 2);
        !           213:                name = name.substr(1, len);
        !           214:                attr = TA::Disable;
        !           215:        } else {
        !           216:                name = name.substr(0, 7);
        !           217:                attr = TA::Normal;
        !           218:        }
        !           219: 
        !           220:        return std::make_pair(name, attr);
        !           221: }
        !           222: 
1.1       root      223: // Mainbus は1つしかないので、スタティック変数にしておく。
                    224: /*static*/ std::array<IODevice *, 256> MainbusDevice::devtable;
                    225: 
                    226: // RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を
                    227: // 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。
                    228: // 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを
                    229: // 計算する分を回避したい。
                    230: /*static*/ int MainbusDevice::direct_ram_size;

unix.superglobalmegacorp.com

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