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

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: {
        !            18: }
        !            19: 
        !            20: // デストラクタ
        !            21: MainbusDevice::~MainbusDevice()
        !            22: {
        !            23: }
        !            24: 
        !            25: uint64
        !            26: MainbusDevice::Read8(uint32 addr)
        !            27: {
        !            28:        uint64 data;
        !            29: 
        !            30:        if (addr < direct_ram_size) {
        !            31:                data = MainRAMDevice::mainram[HLB(addr)];
        !            32:        } else {
        !            33:                IODevice *dev = devtable[addr >> 24];
        !            34:                data = dev->Read8(addr);
        !            35:        }
        !            36:        return data;
        !            37: }
        !            38: 
        !            39: uint64
        !            40: MainbusDevice::Read16(uint32 addr)
        !            41: {
        !            42:        uint64 data;
        !            43: 
        !            44:        if (__predict_false((addr & 1) != 0))
        !            45:                VMPANIC("unaligned access $%08x", addr);
        !            46: 
        !            47:        if (addr < direct_ram_size) {
        !            48:                data = *(uint16 *)&MainRAMDevice::mainram[HLW(addr)];
        !            49:        } else {
        !            50:                IODevice *dev = devtable[addr >> 24];
        !            51:                data = dev->Read16(addr);
        !            52:        }
        !            53:        return data;
        !            54: }
        !            55: 
        !            56: uint64
        !            57: MainbusDevice::Read32(uint32 addr)
        !            58: {
        !            59:        uint64 data;
        !            60: 
        !            61:        if (__predict_false((addr & 3) != 0))
        !            62:                VMPANIC("unaligned access $%08x", addr);
        !            63: 
        !            64:        if (addr < direct_ram_size) {
        !            65:                data = *(uint32 *)&MainRAMDevice::mainram[addr];
        !            66:        } else {
        !            67:                IODevice *dev = devtable[addr >> 24];
        !            68:                data = dev->Read32(addr);
        !            69:        }
        !            70:        return data;
        !            71: }
        !            72: 
        !            73: uint64
        !            74: MainbusDevice::Write8(uint32 addr, uint32 data)
        !            75: {
        !            76:        if (addr < direct_ram_size) {
        !            77:                MainRAMDevice::mainram[HLB(addr)] = data;
        !            78:                return 0;
        !            79:        } else {
        !            80:                IODevice *dev = devtable[addr >> 24];
        !            81:                return dev->Write8(addr, data);
        !            82:        }
        !            83: }
        !            84: 
        !            85: uint64
        !            86: MainbusDevice::Write16(uint32 addr, uint32 data)
        !            87: {
        !            88:        if (__predict_false((addr & 1) != 0))
        !            89:                VMPANIC("unaligned access $%08x", addr);
        !            90: 
        !            91:        if (addr < direct_ram_size) {
        !            92:                *(uint16 *)&MainRAMDevice::mainram[HLW(addr)] = data;
        !            93:                return 0;
        !            94:        } else {
        !            95:                IODevice *dev = devtable[addr >> 24];
        !            96:                return dev->Write16(addr, data);
        !            97:        }
        !            98: }
        !            99: 
        !           100: uint64
        !           101: MainbusDevice::Write32(uint32 addr, uint32 data)
        !           102: {
        !           103:        if (__predict_false((addr & 3) != 0))
        !           104:                VMPANIC("unaligned access $%08x", addr);
        !           105: 
        !           106:        if (addr < direct_ram_size) {
        !           107:                *(uint32 *)&MainRAMDevice::mainram[addr] = data;
        !           108:                return 0;
        !           109:        } else {
        !           110:                IODevice *dev = devtable[addr >> 24];
        !           111:                return dev->Write32(addr, data);
        !           112:        }
        !           113: }
        !           114: 
        !           115: uint64
        !           116: MainbusDevice::Peek8(uint32 addr)
        !           117: {
        !           118:        uint64 data;
        !           119: 
        !           120:        if (addr < direct_ram_size) {
        !           121:                data = MainRAMDevice::mainram[HLB(addr)];
        !           122:        } else {
        !           123:                IODevice *dev = devtable[addr >> 24];
        !           124:                data = dev->Peek8(addr);
        !           125:        }
        !           126:        return data;
        !           127: }
        !           128: 
        !           129: // これだけオーバーライドではないので注意。
        !           130: uint64
        !           131: MainbusDevice::Peek32(uint32 addr)
        !           132: {
        !           133:        uint64 data;
        !           134: 
        !           135:        if (__predict_false((addr & 3) != 0))
        !           136:                VMPANIC("unaligned access $%08x", addr);
        !           137: 
        !           138:        if (addr < direct_ram_size) {
        !           139:                data  = *(uint32 *)&MainRAMDevice::mainram[addr];
        !           140:        } else {
        !           141:                IODevice *dev = devtable[addr >> 24];
        !           142:                data  = dev->Peek8(addr++) << 24;
        !           143:                data |= dev->Peek8(addr++) << 16;
        !           144:                data |= dev->Peek8(addr++) << 8;
        !           145:                data |= dev->Peek8(addr);
        !           146:        }
        !           147:        return data;
        !           148: }
        !           149: 
        !           150: // このアドレスを担当する次段の IODevice を返す (IOContainerDevice 用)
        !           151: IODevice *
        !           152: MainbusDevice::GetDevice(uint32 addr) const
        !           153: {
        !           154:        return devtable[addr >> 24];
        !           155: }
        !           156: 
        !           157: // デバイスをセットする。すでにあれば更新する。
        !           158: // idx は devtable[] のインデックス (16MB 単位)。
        !           159: /*static*/ void
        !           160: MainbusDevice::SetDevice(int idx, IODevice *dev)
        !           161: {
        !           162:        assert(idx < devtable.size());
        !           163: 
        !           164:        devtable[idx] = dev;
        !           165: }
        !           166: 
        !           167: // デバイステーブルの src から len 個を dst にコピーする。(ミラーを作る)
        !           168: /*static*/ void
        !           169: MainbusDevice::CopyDevtable(int dst, int src, int len)
        !           170: {
        !           171:        memcpy(&devtable[dst], &devtable[src], sizeof(devtable[0]) * len);
        !           172: }
        !           173: 
        !           174: // Mainbus は1つしかないので、スタティック変数にしておく。
        !           175: /*static*/ std::array<IODevice *, 256> MainbusDevice::devtable;
        !           176: 
        !           177: // RAM へのアクセスは、アクセスアドレスが direct_ram_size 未満なら ram[] を
        !           178: // 直接アクセスし、そうでなければデバイスクラス経由でアクセスする。
        !           179: // 高速モードでは RAM デバイスを経由すること自体とその中でアクセスウェイトを
        !           180: // 計算する分を回避したい。
        !           181: /*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.