Annotation of nono/vm/rom.cpp, revision 1.1.1.14

1.1       root        1: //
                      2: // nono
1.1.1.3   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
1.1.1.7   root        7: //
1.1.1.9   root        8: // ROM の基本クラス
                      9: //
                     10: 
1.1.1.7   root       11: // IODevice
                     12: //    |
                     13: //    |  +-----------+
                     14: //    +--| ROMDevice | (LoadROM()、ウェイト、マスク等を持つ)
                     15: //    |  +-----------+
                     16: //    |     |
                     17: //    |     +-- PROMDevice    (LUNA* の PROM)
                     18: //    |     +-- IPLROM1Device (X680x0 の IPLROM 後半)
                     19: //    |     +-- IPLROM2Device (X680x0 の IPLROM 前半)
                     20: //    |     +-- CGROMDevice   (X680x0 の CGROM)
                     21: //    |     +-- LunaPROMEmuDevice (LUNA PROM エミュレーションの共通部分)
                     22: //    |           |
1.1.1.11  root       23: //    |           +-- Luna1PROMEmuDevice   (LUNA-I の PROM エミュレーション)
                     24: //    |           +-- Luna88kPROMEmuDevice (LUNA-88K の PROM エミュレーション)
1.1.1.7   root       25: //    |
                     26: //    +-- PROM0Device   (LUNA* のブートページ切り替え用プロキシ)
                     27: //    +-- IPLROM0Device (X680x0 のブートページ切り替え用プロキシ)
                     28: 
1.1       root       29: #include "rom.h"
1.1.1.7   root       30: #include "autofd.h"
1.1.1.3   root       31: #include "mainapp.h"
1.1.1.5   root       32: #include "mpu.h"
1.1.1.7   root       33: #include <fcntl.h>
                     34: #include <unistd.h>
                     35: #include <sys/stat.h>
1.1       root       36: 
                     37: //
                     38: // ROM 共通部
                     39: //
                     40: 
1.1.1.13  root       41: ROMDevice::ROMDevice(uint objid_)
1.1.1.11  root       42:        : inherited(objid_)
1.1       root       43: {
                     44:        mask = 0xffffffff;
                     45: }
                     46: 
                     47: ROMDevice::~ROMDevice()
                     48: {
                     49: }
                     50: 
1.1.1.14! root       51: // ROM 用の領域を用意する。
        !            52: bool
        !            53: ROMDevice::AllocROM(uint len, uint8 fill)
        !            54: {
        !            55:        imagebuf.reset(new(std::nothrow) uint8 [len]);
        !            56:        if ((bool)imagebuf == false) {
        !            57:                warnx("Cannot allocate %u bytes at %s", len, __method__);
        !            58:                return false;
        !            59:        }
        !            60:        memset(&imagebuf[0], fill, len);
        !            61:        mem = &imagebuf[0];
        !            62:        mask = len - 1;
        !            63: 
        !            64:        return true;
        !            65: }
        !            66: 
1.1       root       67: // name の ROM を探してロードする。
                     68: // name はパスを含まないファイル名のみ。パスはこちらで探す。
                     69: // 失敗した場合はエラーメッセージを表示して false を返す。
                     70: bool
1.1.1.13  root       71: ROMDevice::LoadROM(const char *name, uint size)
1.1       root       72: {
1.1.1.7   root       73:        struct stat st;
                     74: 
1.1.1.13  root       75:        assert(size != 0);
1.1.1.7   root       76: 
                     77:        // ファイル名
1.1.1.3   root       78:        filename = gMainApp.SearchFile(name);
1.1       root       79:        if (filename.empty()) {
1.1.1.2   root       80:                warnx("%s not found", name);
1.1       root       81:                return false;
                     82:        }
                     83: 
1.1.1.7   root       84:        // メモリを確保
1.1.1.14! root       85:        imagebuf.reset(new(std::nothrow) uint8 [size]);
1.1.1.7   root       86:        if ((bool)imagebuf == false) {
1.1.1.13  root       87:                warnx("ROM \"%s\": Cannot allocate memory (%u bytes)",
1.1.1.7   root       88:                        filename.c_str(), size);
                     89:                return false;
                     90:        }
                     91: 
1.1       root       92:        // オープン
1.1.1.7   root       93:        autofd fd = open(filename.c_str(), O_RDONLY);
                     94:        if (fd < 0) {
                     95:                warn("ROM \"%s\"", filename.c_str());
1.1       root       96:                return false;
                     97:        }
                     98: 
1.1.1.7   root       99:        // ファイルサイズを調べる
                    100:        if (fstat(fd, &st) < 0) {
                    101:                warn("ROM \"%s\" stat failed", filename.c_str());
                    102:                return false;
                    103:        }
                    104: 
                    105:        if (st.st_size < size) {
1.1.1.13  root      106:                warnx("ROM \"%s\" is too short (filesize is expected %u but %jd)",
1.1.1.7   root      107:                        filename.c_str(), size, (intmax_t)st.st_size);
                    108:                return false;
                    109:        }
                    110:        if (st.st_size > size) {
                    111:                // 大きすぎるほうはワーニングだけでいいか
1.1.1.13  root      112:                warnx("%s is too large (ignore %zu bytes)",
                    113:                        filename.c_str(), (size_t)st.st_size - size);
1.1.1.7   root      114:        }
                    115: 
                    116:        // 読み込む
                    117:        ssize_t n = read(fd, &imagebuf[0], size);
                    118:        if (n < 0) {
                    119:                warn("ROM \"%s\" read failed", filename.c_str());
                    120:                return false;
                    121:        }
                    122:        if (n < size) {
                    123:                warnx("ROM \"%s\" read too short", filename.c_str());
                    124:                return false;
                    125:        }
                    126: 
                    127:        fd.Close();
                    128: 
                    129:        mem = &imagebuf[0];
1.1       root      130:        return true;
                    131: }
                    132: 
1.1.1.12  root      133: busdata
1.1.1.13  root      134: ROMDevice::Read(busaddr addr)
1.1       root      135: {
1.1.1.12  root      136:        busdata data;
1.1       root      137: 
1.1.1.13  root      138:        uint32 paddr = addr.Addr() & ~3U;
                    139:        data = be32toh(*(const uint32 *)&mem[paddr & mask]);
1.1.1.12  root      140:        data |= wait;
1.1.1.13  root      141:        data |= BusData::Size4;
                    142:        putlog(4, "$%08x -> $%08x", paddr, data.Data());
1.1.1.8   root      143:        return data;
1.1       root      144: }
                    145: 
1.1.1.12  root      146: busdata
1.1.1.13  root      147: ROMDevice::Write(busaddr addr, uint32 data)
1.1       root      148: {
1.1.1.12  root      149:        busdata r = write_op;
1.1.1.13  root      150:        putlog(4, "$%08x.%u <- $%0*x", addr.Addr(), addr.GetSize(),
                    151:                addr.GetSize() * 2, data);
1.1.1.12  root      152:        r |= wait;
1.1.1.13  root      153:        r |= BusData::Size4;
1.1.1.12  root      154:        return r;
1.1       root      155: }
                    156: 
1.1.1.12  root      157: busdata
1.1.1.13  root      158: ROMDevice::Peek1(uint32 addr)
1.1       root      159: {
                    160:        return mem[addr & mask];
                    161: }
1.1.1.10  root      162: 
1.1.1.12  root      163: // アクセスウェイト [clock] を設定。
                    164: void
                    165: ROMDevice::SetWait(uint32 wait_)
                    166: {
                    167:        uint32 clock_nsec = mpu->GetClock_nsec();
                    168: 
                    169:        wait = busdata::Wait(wait_ * clock_nsec);
                    170: }
                    171: 
1.1.1.10  root      172: // ファイル名を返す。なければ NULL を返す。
                    173: const char *
                    174: ROMDevice::GetFilename() const
                    175: {
                    176:        if (filename.empty()) {
                    177:                return NULL;
                    178:        } else {
                    179:                return filename.c_str();
                    180:        }
                    181: }

unix.superglobalmegacorp.com

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