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

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.11  root       41: ROMDevice::ROMDevice(int objid_)
                     42:        : inherited(objid_)
1.1       root       43: {
                     44:        mask = 0xffffffff;
                     45: }
                     46: 
                     47: ROMDevice::~ROMDevice()
                     48: {
                     49: }
                     50: 
                     51: // name の ROM を探してロードする。
                     52: // name はパスを含まないファイル名のみ。パスはこちらで探す。
                     53: // 失敗した場合はエラーメッセージを表示して false を返す。
                     54: bool
                     55: ROMDevice::LoadROM(const char *name, int size)
                     56: {
1.1.1.7   root       57:        struct stat st;
                     58: 
                     59:        assert(size > 0);
                     60: 
                     61:        // ファイル名
1.1.1.3   root       62:        filename = gMainApp.SearchFile(name);
1.1       root       63:        if (filename.empty()) {
1.1.1.2   root       64:                warnx("%s not found", name);
1.1       root       65:                return false;
                     66:        }
                     67: 
1.1.1.7   root       68:        // メモリを確保
                     69:        imagebuf.reset(new uint8 [size]);
                     70:        if ((bool)imagebuf == false) {
                     71:                warnx("ROM \"%s\": Cannot allocate memory (%d bytes)",
                     72:                        filename.c_str(), size);
                     73:                return false;
                     74:        }
                     75: 
1.1       root       76:        // オープン
1.1.1.7   root       77:        autofd fd = open(filename.c_str(), O_RDONLY);
                     78:        if (fd < 0) {
                     79:                warn("ROM \"%s\"", filename.c_str());
1.1       root       80:                return false;
                     81:        }
                     82: 
1.1.1.7   root       83:        // ファイルサイズを調べる
                     84:        if (fstat(fd, &st) < 0) {
                     85:                warn("ROM \"%s\" stat failed", filename.c_str());
                     86:                return false;
                     87:        }
                     88: 
                     89:        if (st.st_size < size) {
                     90:                warnx("ROM \"%s\" is too short (filesize is expected %d but %jd)",
                     91:                        filename.c_str(), size, (intmax_t)st.st_size);
                     92:                return false;
                     93:        }
                     94:        if (st.st_size > size) {
                     95:                // 大きすぎるほうはワーニングだけでいいか
                     96:                warnx("%s is too large (ignore %zd bytes)",
                     97:                        filename.c_str(), (ssize_t)st.st_size - size);
                     98:        }
                     99: 
                    100:        // 読み込む
                    101:        ssize_t n = read(fd, &imagebuf[0], size);
                    102:        if (n < 0) {
                    103:                warn("ROM \"%s\" read failed", filename.c_str());
                    104:                return false;
                    105:        }
                    106:        if (n < size) {
                    107:                warnx("ROM \"%s\" read too short", filename.c_str());
                    108:                return false;
                    109:        }
                    110: 
                    111:        fd.Close();
                    112: 
                    113:        mem = &imagebuf[0];
1.1       root      114:        return true;
                    115: }
                    116: 
1.1.1.12! root      117: busdata
1.1       root      118: ROMDevice::Read8(uint32 addr)
                    119: {
1.1.1.12! root      120:        busdata data;
1.1.1.8   root      121:        data = mem[addr & mask];
1.1.1.12! root      122:        data |= wait;
        !           123:        putlog(4, "$%08x.B -> $%02x", addr, data.Data());
1.1.1.8   root      124:        return data;
1.1       root      125: }
                    126: 
1.1.1.12! root      127: busdata
1.1       root      128: ROMDevice::Read16(uint32 addr)
                    129: {
1.1.1.12! root      130:        busdata data;
1.1.1.10  root      131:        data = be16toh(*(const uint16 *)&mem[addr & mask]);
1.1.1.12! root      132:        data |= wait;
        !           133:        putlog(4, "$%08x.W -> $%04x", addr, data.Data());
1.1.1.8   root      134:        return data;
1.1       root      135: }
                    136: 
1.1.1.12! root      137: busdata
1.1       root      138: ROMDevice::Read32(uint32 addr)
                    139: {
1.1.1.12! root      140:        busdata data;
1.1.1.10  root      141:        data = be32toh(*(const uint32 *)&mem[addr & mask]);
1.1.1.12! root      142:        data |= wait;
        !           143:        putlog(4, "$%08x.L -> $%08x", addr, data.Data());
1.1.1.8   root      144:        return data;
1.1       root      145: }
                    146: 
1.1.1.12! root      147: busdata
1.1       root      148: ROMDevice::Write8(uint32 addr, uint32 data)
                    149: {
1.1.1.12! root      150:        busdata r = write_op;
1.1.1.8   root      151:        putlog(4, "$%08x.B <- $%02x", addr, data);
1.1.1.12! root      152:        r |= wait;
        !           153:        return r;
1.1       root      154: }
                    155: 
1.1.1.12! root      156: busdata
1.1       root      157: ROMDevice::Write16(uint32 addr, uint32 data)
                    158: {
1.1.1.12! root      159:        busdata r = write_op;
1.1.1.8   root      160:        putlog(4, "$%08x.W <- $%04x", addr, data);
1.1.1.12! root      161:        r |= wait;
        !           162:        return r;
1.1       root      163: }
                    164: 
1.1.1.12! root      165: busdata
1.1       root      166: ROMDevice::Write32(uint32 addr, uint32 data)
                    167: {
1.1.1.12! root      168:        busdata r = write_op;
1.1.1.8   root      169:        putlog(4, "$%08x.L <- $%08x", addr, data);
1.1.1.12! root      170:        r |= wait;
        !           171:        return r;
1.1       root      172: }
                    173: 
1.1.1.12! root      174: busdata
1.1       root      175: ROMDevice::Peek8(uint32 addr)
                    176: {
                    177:        return mem[addr & mask];
                    178: }
1.1.1.10  root      179: 
1.1.1.12! root      180: // アクセスウェイト [clock] を設定。
        !           181: void
        !           182: ROMDevice::SetWait(uint32 wait_)
        !           183: {
        !           184:        uint32 clock_nsec = mpu->GetClock_nsec();
        !           185: 
        !           186:        wait = busdata::Wait(wait_ * clock_nsec);
        !           187: }
        !           188: 
1.1.1.10  root      189: // ファイル名を返す。なければ NULL を返す。
                    190: const char *
                    191: ROMDevice::GetFilename() const
                    192: {
                    193:        if (filename.empty()) {
                    194:                return NULL;
                    195:        } else {
                    196:                return filename.c_str();
                    197:        }
                    198: }

unix.superglobalmegacorp.com

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