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

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: // SubRAM はバイト配置とする。
                     12: 
                     13: #include "subram.h"
                     14: #include "mainapp.h"
                     15: 
                     16: //
                     17: // 共通クラス
                     18: //
                     19: 
                     20: // コンストラクタ
1.1.1.3   root       21: SubRAMBaseDevice::SubRAMBaseDevice(uint objid_, uint ramsize_kb)
1.1       root       22:        : inherited(objid_)
                     23: {
1.1.1.3   root       24:        uint ramsize = ramsize_kb * 1024;
                     25:        assert((ramsize & (ramsize - 1)) == 0);
1.1       root       26: 
1.1.1.3   root       27:        mask = ramsize - 1;
1.1       root       28: }
                     29: 
                     30: // デストラクタ
                     31: SubRAMBaseDevice::~SubRAMBaseDevice()
                     32: {
                     33: }
                     34: 
1.1.1.4 ! root       35: // 初期化
        !            36: bool
        !            37: SubRAMBaseDevice::Init()
        !            38: {
        !            39:        uint ramsize = GetSize();
        !            40:        ram.reset(new(std::nothrow) uint8[ramsize]);
        !            41:        if ((bool)ram == false) {
        !            42:                warnx("Cannot allocate %u bytes at %s", ramsize, __method__);
        !            43:                return false;
        !            44:        }
        !            45:        memset(&ram[0], 0, ramsize);
        !            46: 
        !            47:        return true;
        !            48: }
        !            49: 
1.1       root       50: // リセット
                     51: void
                     52: SubRAMBaseDevice::ResetHard(bool poweron)
                     53: {
                     54:        if (poweron) {
                     55:                // 実際にはゼロ初期化ではなくゴミだと思うがとりあえず。
1.1.1.3   root       56:                memset(&ram[0], 0, GetSize());
1.1       root       57:        }
                     58: }
                     59: 
                     60: // アドレスデコーダ
1.1.1.2   root       61: inline uint32
1.1       root       62: SubRAMBaseDevice::Decoder(uint32 addr) const
                     63: {
1.1.1.3   root       64:        // たぶんサイズ分で折り返しイメージが見えるはず。要確認。
                     65:        return addr & mask;
1.1       root       66: }
                     67: 
1.1.1.3   root       68: // MPU からのアクセス
1.1.1.2   root       69: busdata
1.1.1.3   root       70: SubRAMBaseDevice::Read(busaddr addr)
1.1       root       71: {
1.1.1.3   root       72:        uint32 offset = Decoder(addr.Addr());
                     73:        busdata data;
                     74: 
                     75:        // MPU からはおそらくロングワードデバイス。
                     76:        data  = be32toh(*(uint32 *)&ram[offset & ~3U]);
                     77:        data |= BusData::Size4;
                     78:        putlog(4, "$%08x -> $%08x", addr.Addr(), data.Data());
1.1       root       79:        return data;
                     80: }
                     81: 
1.1.1.3   root       82: // MPU からのアクセス
                     83: busdata
                     84: SubRAMBaseDevice::Write(busaddr addr, uint32 data)
                     85: {
                     86:        uint32 offset = Decoder(addr.Addr());
                     87:        uint32 reqsize = addr.GetSize();
                     88:        uint32 datasize = std::min(4 - (offset & 3U), reqsize);
                     89: 
                     90:        // MPU からはおそらくロングワードデバイス。
                     91:        if (datasize == 4) {
                     92:                putlog(3, "$%08x <- $%08x", addr.Addr(), data);
                     93:                *(uint32 *)&ram[offset] = htobe32(data);
                     94:        } else if (datasize == 1) {
                     95:                data >>= (reqsize - datasize) * 8;
                     96:                putlog(3, "$%08x <- $%02x", addr.Addr(), data);
                     97:                ram[offset] = data;
                     98:        } else {
                     99:                data >>= (reqsize - datasize) * 8;
                    100:                putlog(3, "$%08x <- $%0*x", addr.Addr(), datasize * 2, data);
                    101:                for (int i = datasize - 1; i >= 0; i--) {
                    102:                        ram[offset + i] = data;
                    103:                        data >>= 8;
                    104:                }
                    105:        }
                    106: 
                    107:        busdata r = BusData::Size4;
                    108:        return r;
                    109: }
                    110: 
1.1.1.2   root      111: busdata
1.1.1.3   root      112: SubRAMBaseDevice::Peek1(uint32 addr)
1.1       root      113: {
                    114:        uint32 offset = Decoder(addr);
1.1.1.3   root      115:        return ram[offset];
                    116: }
                    117: 
                    118: bool
                    119: SubRAMBaseDevice::Poke1(uint32 addr, uint32 data)
                    120: {
                    121:        if ((int32)data >= 0) {
                    122:                uint32 offset = Decoder(addr);
                    123:                ram[offset] = data;
                    124:        }
                    125:        return true;
1.1       root      126: }
                    127: 
1.1.1.3   root      128: // XP からのバイト読み込み。
                    129: // (サイズは自明なので返さない)
1.1.1.2   root      130: busdata
1.1.1.3   root      131: SubRAMBaseDevice::Read1(uint32 addr)
1.1       root      132: {
                    133:        uint32 offset = Decoder(addr);
1.1.1.3   root      134:        busdata data = ram[offset];
                    135:        putlog(4, "XP $%05x -> $%02x", offset, data.Data());
1.1       root      136:        return data;
                    137: }
                    138: 
1.1.1.3   root      139: // XP からのバイト書き込み。
                    140: // (サイズは自明なので返さない)
1.1.1.2   root      141: busdata
1.1.1.3   root      142: SubRAMBaseDevice::Write1(uint32 addr, uint32 data)
1.1       root      143: {
                    144:        uint32 offset = Decoder(addr);
1.1.1.3   root      145:        putlog(3, "XP $%05x <- $%02x", offset, data);
1.1       root      146:        ram[offset] = data;
                    147:        return 0;
                    148: }
                    149: 
1.1.1.3   root      150: // Lance からのワード読み込み。addr は偶数であること。
                    151: // (サイズは自明なので返さない)
1.1.1.2   root      152: busdata
1.1.1.3   root      153: SubRAMBaseDevice::Read2(uint32 addr)
1.1       root      154: {
1.1.1.3   root      155:        busdata data = Peek2(addr);
                    156:        putlog(4, "LE $%05x -> $%04x", Decoder(addr), data.Data());
                    157:        return data;
1.1       root      158: }
                    159: 
1.1.1.3   root      160: // Lance からのワード書き込み。addr は偶数であること。
                    161: // (サイズは自明なので返さない)
1.1.1.2   root      162: busdata
1.1.1.3   root      163: SubRAMBaseDevice::Write2(uint32 addr, uint32 data)
1.1       root      164: {
                    165:        uint32 offset = Decoder(addr);
1.1.1.3   root      166:        putlog(3, "LE $%05x <- $%04x", offset, data);
                    167:        *(uint16 *)&ram[offset] = htobe16(data);
1.1       root      168:        return 0;
                    169: }
                    170: 
1.1.1.3   root      171: // Lance からのピーク。addr は偶数であること。
1.1.1.2   root      172: busdata
1.1.1.3   root      173: SubRAMBaseDevice::Peek2(uint32 addr) const
1.1       root      174: {
                    175:        uint32 offset = Decoder(addr);
1.1.1.3   root      176:        busdata data = be16toh(*(uint16 *)&ram[offset]);
                    177:        return data;
1.1       root      178: }
                    179: 
                    180: 
                    181: //
1.1.1.3   root      182: // サブメモリ 1 (XP/Lance との共有 RAM)
1.1       root      183: //
                    184: 
                    185: // コンストラクタ
1.1.1.3   root      186: SubRAMDevice::SubRAMDevice(uint ramsize_kb)
1.1       root      187:        : inherited(OBJ_SUBRAM, ramsize_kb)
                    188: {
                    189: }
                    190: 
                    191: // デストラクタ
                    192: SubRAMDevice::~SubRAMDevice()
                    193: {
                    194: }
                    195: 
                    196: // リセット
                    197: void
                    198: SubRAMDevice::ResetHard(bool poweron)
                    199: {
                    200:        // 通常モードなら電源オンで初期化。
                    201:        // MSXDOS モードなら MSXDOSDevice::Init() がすでにここに
                    202:        // 書き込んでいるため、消してはいけない。
                    203:        if (gMainApp.msxdos_mode == false) {
                    204:                inherited::ResetHard(poweron);
                    205:        }
                    206: }
                    207: 
                    208: 
                    209: //
1.1.1.3   root      210: // サブメモリ 2 (XP の非共有部)
1.1       root      211: //
                    212: 
                    213: // コンストラクタ
1.1.1.3   root      214: SubRAM2Device::SubRAM2Device(uint ramsize_kb)
1.1       root      215:        : inherited(OBJ_SUBRAM2, ramsize_kb)
                    216: {
                    217: }
                    218: 
                    219: // デストラクタ
                    220: SubRAM2Device::~SubRAM2Device()
                    221: {
                    222: }

unix.superglobalmegacorp.com

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