Annotation of nono/vm/mainbus.cpp, revision 1.1.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.