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

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2017 [email protected]
                      4: //
                      5: 
1.1.1.3 ! root        6: #include "mainapp.h"
1.1       root        7: #include "sram.h"
                      8: #include <sys/fcntl.h>
                      9: #include <sys/mman.h>
1.1.1.2   root       10: #include <sys/stat.h>
1.1       root       11: 
                     12: //
                     13: // SRAM
                     14: //
                     15: // SRAM はビッグエンディアンのままメモリに置かれるので、
                     16: // 必要ならアクセス時に都度変換すること。
                     17: //
                     18: 
1.1.1.3 ! root       19: std::unique_ptr<SRAMDevice> gSRAM;
1.1       root       20: 
                     21: SRAMDevice::SRAMDevice()
                     22: {
                     23:        logname = "sram";
                     24:        devname = "SRAM";
                     25:        devaddr = baseaddr;
                     26:        devlen  = 0x10000;      // 通常実際は16KBだが64KB分占有しておく
                     27: 
                     28:        fd = -1;
                     29: }
                     30: 
                     31: SRAMDevice::~SRAMDevice()
                     32: {
                     33:        if (mem) {
                     34:                munmap(mem, memlen);
                     35:                mem = NULL;
                     36:                memlen = 0;
                     37:        }
                     38:        if (fd >= 0) {
                     39:                close(fd);
                     40:                fd = -1;
                     41:        }
                     42: }
                     43: 
                     44: bool
                     45: SRAMDevice::Init()
                     46: {
1.1.1.2   root       47:        struct stat st;
                     48: 
1.1.1.3 ! root       49:        filename = gMainApp.GetVMDir() + "SRAM030.DAT";
1.1.1.2   root       50:        memlen = 16 * 1024;
1.1       root       51: 
                     52:        fd = open(filename.c_str(), O_RDWR);
                     53:        if (fd == -1) {
1.1.1.2   root       54:                warn("SRAM \"%s\" open failed", filename.c_str());
1.1       root       55:                return false;
                     56:        }
                     57: 
1.1.1.2   root       58:        // ファイルサイズをチェック。
                     59:        // ファイルが短くても mmap はしれっと成功してしまうようだ。
                     60:        if (fstat(fd, &st) == -1) {
                     61:                warn("SRAM \"%s\" fstat failed", filename.c_str());
                     62:                close(fd);
                     63:                return false;
                     64:        }
                     65:        if (st.st_size < memlen) {
                     66:                warnx("SRAM \"%s\" is too short (filesize is expected %d but %d)",
                     67:                        filename.c_str(), memlen, (int)st.st_size);
                     68:                close(fd);
                     69:                return false;
                     70:        }
                     71:        if (st.st_size > memlen) {
                     72:                // 大きすぎるほうはワーニングだけでいいか
                     73:                warnx("SRAM \"%s\" is too large (ignore %d bytes)",
                     74:                        filename.c_str(), (int)st.st_size - memlen);
                     75:        }
                     76: 
1.1       root       77:        mem = (uint8 *)mmap(NULL, memlen, PROT_READ | PROT_WRITE,
                     78:                MAP_SHARED, fd, 0);
                     79:        if (mem == MAP_FAILED) {
1.1.1.2   root       80:                warn("SRAM \"%s\" mmap failed", filename.c_str());
1.1       root       81:                close(fd);
                     82:                return false;
                     83:        }
                     84: 
                     85:        return true;
                     86: }
                     87: 
1.1.1.3 ! root       88: // アドレスデコーダ
        !            89: inline uint64
        !            90: SRAMDevice::Decoder(uint32 addr) const
        !            91: {
        !            92:        return addr - baseaddr;
        !            93: }
        !            94: 
1.1       root       95: uint64
                     96: SRAMDevice::Read8(uint32 addr)
                     97: {
1.1.1.3 ! root       98:        uint32 offset = Decoder(addr);
        !            99:        return mem[offset];
1.1       root      100: }
                    101: 
                    102: uint64
                    103: SRAMDevice::Read16(uint32 addr)
                    104: {
1.1.1.3 ! root      105:        uint32 offset = Decoder(addr);
        !           106:        return be16toh(*(uint16 *)&mem[offset]);
1.1       root      107: }
                    108: 
                    109: uint64
                    110: SRAMDevice::Write8(uint32 addr, uint32 data)
                    111: {
1.1.1.3 ! root      112:        uint32 offset = Decoder(addr);
        !           113: 
1.1       root      114:        if (writeable) {
1.1.1.3 ! root      115:                if (offset < 0x100) {
1.1       root      116:                        putlog(1, "更新 $%06x <- $%02x", addr, data);
                    117:                }
1.1.1.3 ! root      118:                mem[offset] = data;
1.1       root      119:        } else {
                    120:                putlog(1, "書き込み禁止 $%06x <- $%02x", addr, data);
                    121:        }
                    122:        return 0;
                    123: }
                    124: 
                    125: uint64
                    126: SRAMDevice::Write16(uint32 addr, uint32 data)
                    127: {
1.1.1.3 ! root      128:        uint32 offset = Decoder(addr);
        !           129: 
1.1       root      130:        if (writeable) {
1.1.1.3 ! root      131:                if (offset < 0x100) {
1.1       root      132:                        putlog(1, "更新 $%06x <- $%04x", addr, data);
                    133:                }
1.1.1.3 ! root      134:                *(uint16 *)&mem[offset] = htobe16(data);
1.1       root      135:        } else {
                    136:                putlog(1, "書き込み禁止 $%06x <- $%04x", addr, data);
                    137:        }
                    138:        return 0;
                    139: }
                    140: 
                    141: uint64
                    142: SRAMDevice::Peek8(uint32 addr)
                    143: {
1.1.1.3 ! root      144:        uint32 offset = Decoder(addr);
        !           145:        return mem[offset];
1.1       root      146: }
                    147: 
                    148: void
                    149: SRAMDevice::write_enable(bool value)
                    150: {
                    151:        if (writeable == false && value == true) {
                    152:                putlog(1, "書き込み許可");
                    153:        } else if (writeable == true && value == false) {
                    154:                putlog(1, "書き込み禁止");
                    155:        }
                    156: 
                    157:        writeable = value;
                    158: }

unix.superglobalmegacorp.com

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