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

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 用の領域を用意する。
1.1.1.15! root       52: // 失敗した場合は warn 系でエラーメッセージを表示して false を返す。
1.1.1.14  root       53: bool
                     54: ROMDevice::AllocROM(uint len, uint8 fill)
                     55: {
                     56:        imagebuf.reset(new(std::nothrow) uint8 [len]);
                     57:        if ((bool)imagebuf == false) {
1.1.1.15! root       58:                warnx("Could not allocate %u bytes at %s", len, __method__);
1.1.1.14  root       59:                return false;
                     60:        }
                     61:        memset(&imagebuf[0], fill, len);
                     62:        mem = &imagebuf[0];
                     63:        mask = len - 1;
                     64: 
                     65:        return true;
                     66: }
                     67: 
1.1       root       68: // name の ROM を探してロードする。
                     69: // name はパスを含まないファイル名のみ。パスはこちらで探す。
1.1.1.15! root       70: // 失敗した場合は warn 系でエラーメッセージを表示して false を返す。
1.1       root       71: bool
1.1.1.13  root       72: ROMDevice::LoadROM(const char *name, uint size)
1.1       root       73: {
1.1.1.7   root       74:        struct stat st;
                     75: 
1.1.1.13  root       76:        assert(size != 0);
1.1.1.7   root       77: 
                     78:        // ファイル名
1.1.1.3   root       79:        filename = gMainApp.SearchFile(name);
1.1       root       80:        if (filename.empty()) {
1.1.1.2   root       81:                warnx("%s not found", name);
1.1       root       82:                return false;
                     83:        }
                     84: 
1.1.1.7   root       85:        // メモリを確保
1.1.1.14  root       86:        imagebuf.reset(new(std::nothrow) uint8 [size]);
1.1.1.7   root       87:        if ((bool)imagebuf == false) {
1.1.1.15! root       88:                warnx("ROM \"%s\": Could not allocate %u bytes",
1.1.1.7   root       89:                        filename.c_str(), size);
                     90:                return false;
                     91:        }
                     92: 
1.1       root       93:        // オープン
1.1.1.7   root       94:        autofd fd = open(filename.c_str(), O_RDONLY);
                     95:        if (fd < 0) {
                     96:                warn("ROM \"%s\"", filename.c_str());
1.1       root       97:                return false;
                     98:        }
                     99: 
1.1.1.7   root      100:        // ファイルサイズを調べる
                    101:        if (fstat(fd, &st) < 0) {
                    102:                warn("ROM \"%s\" stat failed", filename.c_str());
                    103:                return false;
                    104:        }
                    105: 
                    106:        if (st.st_size < size) {
1.1.1.13  root      107:                warnx("ROM \"%s\" is too short (filesize is expected %u but %jd)",
1.1.1.7   root      108:                        filename.c_str(), size, (intmax_t)st.st_size);
                    109:                return false;
                    110:        }
                    111:        if (st.st_size > size) {
                    112:                // 大きすぎるほうはワーニングだけでいいか
1.1.1.13  root      113:                warnx("%s is too large (ignore %zu bytes)",
                    114:                        filename.c_str(), (size_t)st.st_size - size);
1.1.1.7   root      115:        }
                    116: 
                    117:        // 読み込む
                    118:        ssize_t n = read(fd, &imagebuf[0], size);
                    119:        if (n < 0) {
                    120:                warn("ROM \"%s\" read failed", filename.c_str());
                    121:                return false;
                    122:        }
                    123:        if (n < size) {
                    124:                warnx("ROM \"%s\" read too short", filename.c_str());
                    125:                return false;
                    126:        }
                    127: 
                    128:        fd.Close();
                    129: 
                    130:        mem = &imagebuf[0];
1.1       root      131:        return true;
                    132: }
                    133: 
1.1.1.12  root      134: busdata
1.1.1.13  root      135: ROMDevice::Read(busaddr addr)
1.1       root      136: {
1.1.1.12  root      137:        busdata data;
1.1       root      138: 
1.1.1.13  root      139:        uint32 paddr = addr.Addr() & ~3U;
                    140:        data = be32toh(*(const uint32 *)&mem[paddr & mask]);
1.1.1.12  root      141:        data |= wait;
1.1.1.13  root      142:        data |= BusData::Size4;
                    143:        putlog(4, "$%08x -> $%08x", paddr, data.Data());
1.1.1.8   root      144:        return data;
1.1       root      145: }
                    146: 
1.1.1.12  root      147: busdata
1.1.1.13  root      148: ROMDevice::Write(busaddr addr, uint32 data)
1.1       root      149: {
1.1.1.12  root      150:        busdata r = write_op;
1.1.1.13  root      151:        putlog(4, "$%08x.%u <- $%0*x", addr.Addr(), addr.GetSize(),
                    152:                addr.GetSize() * 2, data);
1.1.1.12  root      153:        r |= wait;
1.1.1.13  root      154:        r |= BusData::Size4;
1.1.1.12  root      155:        return r;
1.1       root      156: }
                    157: 
1.1.1.12  root      158: busdata
1.1.1.13  root      159: ROMDevice::Peek1(uint32 addr)
1.1       root      160: {
                    161:        return mem[addr & mask];
                    162: }
1.1.1.10  root      163: 
1.1.1.12  root      164: // アクセスウェイト [clock] を設定。
                    165: void
                    166: ROMDevice::SetWait(uint32 wait_)
                    167: {
1.1.1.15! root      168:        wait = busdata::Wait(wait_ * mpu->GetClock_tsec());
1.1.1.12  root      169: }
                    170: 
1.1.1.10  root      171: // ファイル名を返す。なければ NULL を返す。
                    172: const char *
                    173: ROMDevice::GetFilename() const
                    174: {
                    175:        if (filename.empty()) {
                    176:                return NULL;
                    177:        } else {
                    178:                return filename.c_str();
                    179:        }
                    180: }

unix.superglobalmegacorp.com

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