Annotation of nono/vm/sram.cpp, revision 1.1.1.17

1.1       root        1: //
                      2: // nono
1.1.1.4   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: //
                      8: // SRAM
                      9: //
1.1.1.9   root       10: 
1.1       root       11: // SRAM はビッグエンディアンのままメモリに置かれるので、
                     12: // 必要ならアクセス時に都度変換すること。
                     13: 
1.1.1.9   root       14: #include "sram.h"
1.1.1.10  root       15: #include "config.h"
1.1.1.9   root       16: #include "mainapp.h"
1.1.1.11  root       17: #include "mainram.h"
1.1.1.13  root       18: #include <sys/mman.h>
1.1.1.9   root       19: 
                     20: // コンストラクタ
1.1       root       21: SRAMDevice::SRAMDevice()
1.1.1.11  root       22:        : inherited(OBJ_SRAM)
1.1       root       23: {
                     24: }
                     25: 
1.1.1.9   root       26: // デストラクタ
1.1       root       27: SRAMDevice::~SRAMDevice()
                     28: {
1.1.1.13  root       29:        if ((bool)file) {
                     30:                // この場合は mem は file が管理している。
                     31:                file.reset();
                     32:        } else {
                     33:                if (mem) {
                     34:                        munmap(mem, sramsize);
                     35:                }
                     36:        }
1.1       root       37: }
                     38: 
1.1.1.11  root       39: // 初期化
1.1       root       40: bool
                     41: SRAMDevice::Init()
                     42: {
1.1.1.13  root       43:        // SRAM ファイルをオープン。
                     44:        if (gMainApp.GetVMDir().empty()) {
1.1.1.16  root       45:                // VM ディレクトリ指定がなければ、オンメモリに初期値を用意する。
                     46:                // Human68k モードで VM ディレクトリを指定しない場合に起きる。
1.1.1.13  root       47:                void *m = mmap(NULL, sramsize, PROT_READ | PROT_WRITE,
                     48:                        MAP_ANON | MAP_SHARED, -1, 0);
                     49:                if (m == MAP_FAILED) {
1.1.1.17! root       50:                        warn("%s: mmap", __method__);
1.1.1.13  root       51:                        return false;
                     52:                }
                     53:                mem = (uint8 *)m;
1.1.1.16  root       54:                memcpy(mem, &initialdata[0], initialdata.size());
1.1.1.13  root       55:        } else {
1.1.1.16  root       56:                // VM ディレクトリ指定があれば、ファイルを開く。
1.1.1.13  root       57:                filename = gMainApp.GetVMDir() + "SRAM.DAT";
1.1.1.15  root       58:                try {
                     59:                        file.reset(new MappedFile());
                     60:                } catch (...) { }
                     61:                if ((bool)file == false) {
                     62:                        warnx("Failed to initialize MappedFile at %s", __method__);
                     63:                        return false;
                     64:                }
1.1.1.13  root       65:                file->SetFilename(filename);
                     66:                file->SetDispname(string_format("SRAM \"%s\"", filename.c_str()));
1.1.1.16  root       67:                mem = file->OpenCreate(sramsize, &initialdata[0], initialdata.size());
1.1.1.13  root       68:                if (mem == NULL) {
1.1.1.17! root       69:                        // エラーメッセージは表示済み。
1.1.1.13  root       70:                        return false;
                     71:                }
1.1       root       72:        }
                     73: 
1.1.1.10  root       74:        // SRAM の RAM 容量欄を設定値に同期させる。
                     75:        // この処理はアプリケーション起動時に一回行われるのみで、
                     76:        // その後の VM 内のリセット等では動作しない。
1.1.1.17! root       77:        if (gConfig->Find("sram-sync-ramsize").AsBool()) {
1.1.1.10  root       78:                SyncRAMSize();
                     79:        }
                     80: 
1.1       root       81:        return true;
                     82: }
                     83: 
1.1.1.9   root       84: // リセット
1.1.1.6   root       85: void
1.1.1.9   root       86: SRAMDevice::ResetHard(bool poweron)
1.1.1.6   root       87: {
                     88:        // XXX 未調査
                     89:        writeable = false;
                     90: }
                     91: 
1.1.1.10  root       92: // SRAM の RAM 容量欄を設定値に同期させる。
                     93: void
                     94: SRAMDevice::SyncRAMSize()
                     95: {
                     96:        // SRAM の内容が無効なら何もしない。
                     97:        static const std::array<uint8, 7> magic {
                     98:                0x82, 0x77, '6', '8', '0', '0', '0'
                     99:        };
                    100:        for (int i = 0; i < magic.size(); i++) {
                    101:                if (mem[i] != magic[i]) {
                    102:                        return;
                    103:                }
                    104:        }
                    105: 
1.1.1.15  root      106:        uint32 ramsize = (uint32)GetMainRAMDevice()->GetSize();
1.1.1.10  root      107: 
                    108:        // 値が違う時だけ表示したいので一旦読み出して比較
                    109:        uint32 cursize;
                    110:        cursize  = mem[0x08] << 24;
                    111:        cursize |= mem[0x09] << 16;
                    112:        cursize |= mem[0x0a] << 8;
                    113:        cursize |= mem[0x0b];
                    114:        if (cursize != ramsize) {
1.1.1.13  root      115:                if (gMainApp.GetVMDir().empty()) {
                    116:                        // Human68k モードで -c のない時は表示不要。ダミー SRAM なので。
                    117:                } else {
                    118:                        warnx("SRAM: Update ramsize %uMB", ramsize / 1024 / 1024);
                    119:                }
1.1.1.10  root      120: 
                    121:                mem[0x08] = ramsize >> 24;
                    122:                mem[0x09] = ramsize >> 16;
                    123:                mem[0x0a] = ramsize >> 8;
                    124:                mem[0x0b] = ramsize;
                    125:        }
                    126: }
                    127: 
1.1.1.3   root      128: // アドレスデコーダ
1.1.1.12  root      129: inline uint32
1.1.1.3   root      130: SRAMDevice::Decoder(uint32 addr) const
                    131: {
1.1.1.4   root      132:        uint32 offset = addr - baseaddr;
1.1.1.13  root      133:        assertmsg(offset < file->GetMemSize(),
                    134:                "offset=%x memlen=%x", offset, (uint)file->GetMemSize());
1.1.1.4   root      135:        return offset;
1.1.1.3   root      136: }
                    137: 
1.1.1.12  root      138: busdata
1.1.1.13  root      139: SRAMDevice::Read(busaddr addr)
1.1       root      140: {
1.1.1.13  root      141:        uint32 offset = Decoder(addr.Addr());
                    142:        busdata data;
1.1.1.4   root      143: 
1.1.1.13  root      144:        data  = Get16(offset & ~1U);
                    145:        data |= BusData::Size2;
                    146:        putlog(2, "$%06x -> $%04x", addr.Addr() & ~1U, data.Data());
1.1.1.4   root      147:        return data;
1.1       root      148: }
                    149: 
1.1.1.12  root      150: busdata
1.1.1.13  root      151: SRAMDevice::Write(busaddr addr, uint32 data)
1.1       root      152: {
1.1.1.13  root      153:        uint32 offset = Decoder(addr.Addr());
                    154:        uint32 reqsize = addr.GetSize();
                    155:        uint32 datasize = std::min(2 - (offset & 1), reqsize);
                    156:        data >>= (reqsize - datasize) * 8;
1.1.1.3   root      157: 
1.1       root      158:        if (writeable) {
1.1.1.3   root      159:                if (offset < 0x100) {
1.1.1.13  root      160:                        putlog(1, "$%06x.%c <- $%0*x", addr.Addr(),
                    161:                                (datasize == 1 ? 'B' : 'W'), datasize * 2, data);
                    162:                }
                    163:                if (datasize == 1) {
                    164:                        mem[offset] = data;
                    165:                } else {
                    166:                        *(uint16 *)&mem[offset] = htobe16(data);
1.1       root      167:                }
                    168:        } else {
1.1.1.13  root      169:                putlog(1, "Write protected $%06x.%c <- $%0*x", addr.Addr(),
                    170:                        (datasize == 1 ? 'B' : 'W'), datasize * 2, data);
1.1       root      171:        }
1.1.1.13  root      172: 
                    173:        busdata r = busdata::Size(datasize);
                    174:        return r;
1.1       root      175: }
                    176: 
1.1.1.12  root      177: busdata
1.1.1.13  root      178: SRAMDevice::Peek1(uint32 addr)
1.1       root      179: {
1.1.1.3   root      180:        uint32 offset = Decoder(addr);
1.1.1.13  root      181:        uint32 data = Get16(offset & ~1U);
1.1.1.3   root      182: 
1.1.1.13  root      183:        if ((offset & 1) == 0) {
                    184:                return data >> 8;
1.1       root      185:        } else {
1.1.1.13  root      186:                return data & 0xff;
1.1       root      187:        }
1.1.1.11  root      188: }
1.1.1.4   root      189: 
1.1.1.12  root      190: bool
1.1.1.13  root      191: SRAMDevice::Poke1(uint32 addr, uint32 data)
1.1.1.11  root      192: {
                    193:        // WriteEnable() に関わらず変更する。
                    194:        // また Get8()、Get16() はこの変更の影響を受けないことに注意。
                    195: 
                    196:        if ((int32)data >= 0) {
                    197:                uint32 offset = Decoder(addr);
                    198:                mem[offset] = data;
                    199:        }
1.1.1.12  root      200:        return true;
1.1       root      201: }
                    202: 
                    203: void
1.1.1.11  root      204: SRAMDevice::WriteEnable(bool value)
1.1       root      205: {
                    206:        if (writeable == false && value == true) {
1.1.1.10  root      207:                putlog(1, "Write Enable");
1.1       root      208:        } else if (writeable == true && value == false) {
1.1.1.10  root      209:                putlog(1, "Write Disable");
1.1       root      210:        }
                    211: 
                    212:        writeable = value;
                    213: }
1.1.1.4   root      214: 
1.1.1.11  root      215: // SRAM から副作用なく読み出す。
                    216: // ただしホストファイル起動モードなら改変した値を返す。
1.1.1.4   root      217: uint32
1.1.1.13  root      218: SRAMDevice::Get16(uint32 offset) const
1.1.1.4   root      219: {
1.1.1.11  root      220:        if (gMainApp.exec_file) {
                    221:                switch (offset) {
                    222:                 case 0x0c:                     // ROM 起動アドレス(.L)
1.1.1.13  root      223:                        return (plutoaddr >> 16) & 0xffff;
1.1.1.11  root      224:                 case 0x0e:
1.1.1.13  root      225:                        return plutoaddr & 0xffff;
1.1.1.11  root      226: 
                    227:                 case 0x18:                     // 起動デバイス(.W) を ROM($a000) にする
1.1.1.13  root      228:                        return 0xa000;
1.1.1.11  root      229: 
                    230:                 default:
                    231:                        break;
                    232:                }
1.1.1.4   root      233:        }
1.1.1.11  root      234: 
                    235:        // 他は SRAM から
1.1.1.13  root      236:        uint32 data = *(uint16 *)&mem[offset];
                    237:        return be16toh(data);
1.1.1.4   root      238: }
1.1.1.10  root      239: 
1.1.1.11  root      240: // SRAM から副作用なくロングワードで読み出す。
                    241: // ただしホストファイル起動モードなら改変した値を返す。
1.1.1.10  root      242: uint32
1.1.1.11  root      243: SRAMDevice::Get32(uint32 offset) const
1.1.1.10  root      244: {
                    245:        uint32 data;
                    246: 
1.1.1.11  root      247:        data  = Get16(offset) << 16;
                    248:        data |= Get16(offset + 2);
1.1.1.10  root      249: 
                    250:        return data;
                    251: }
1.1.1.11  root      252: 
1.1.1.16  root      253: // X68030 が初期化した SRAM の初期値。
1.1.1.11  root      254: //
                    255: // 0000: 82 77 36 38 30 30 30 57  00 40 00 00 00 fc 00 00  |.w68000W.@......|
                    256: // 0010: 00 ed 01 00 ff ff ff ff  00 00 4e 07 00 10 00 00  |..........N.....|
                    257: // 0020: 00 00 ff ff 00 00 07 00  0e 00 0d 00 00 00 00 00  |................|
                    258: // 0030: f8 3e ff c0 ff fe de 6c  40 22 03 02 00 08 00 00  |.>.....l@"......|
                    259: // 0040: 00 00 00 00 00 00 00 00  00 ff f4 00 04 00 01 01  |................|
1.1.1.16  root      260: // 0050: 00 00 00 20 00 03 f9 01 (00 00 00 00 00 00 00 00) |... ............|
                    261: /*static*/ std::array<uint8, 0x58>
                    262: SRAMDevice::initialdata {
1.1.1.11  root      263:        0x82, 0x77, 0x36, 0x38, 0x30, 0x30, 0x30, 0x57,
                    264:        0x00, 0x40, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00,
                    265:        0x00, 0xed, 0x01, 0x00, 0xff, 0xff, 0xff, 0xff,
                    266:        0x00, 0x00, 0x4e, 0x07, 0x00, 0x10, 0x00, 0x00,
                    267:        0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x07, 0x00,
                    268:        0x0e, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
                    269:        0xf8, 0x3e, 0xff, 0xc0, 0xff, 0xfe, 0xde, 0x6c,
                    270:        0x40, 0x22, 0x03, 0x02, 0x00, 0x08, 0x00, 0x00,
                    271:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                    272:        0x00, 0xff, 0xf4, 0x00, 0x04, 0x00, 0x01, 0x01,
                    273:        0x00, 0x00, 0x00, 0x20, 0x00, 0x03, 0xf9, 0x01,
                    274: };

unix.superglobalmegacorp.com

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