Annotation of nono/debugger/debugger_memory.cpp, revision 1.1.1.4

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
1.1.1.3   root        7: //
                      8: // デバッガのメモリアクセスヘルパー(?)
                      9: //
1.1       root       10: 
1.1.1.4 ! root       11: #include "debugger_memory.h"
1.1       root       12: #include "debugger_private.h"
1.1.1.4 ! root       13: #include "device.h"
1.1       root       14: 
                     15: // コンストラクタ
                     16: DebuggerMemoryStream::DebuggerMemoryStream(const DebuggerMD *md_,
1.1.1.4 ! root       17:        const saddr_t& laddr_, MemoryMode access_mode_, MMULookupMode lookup_mode)
1.1       root       18: {
                     19:        md = md_;
1.1.1.4 ! root       20:        assert(md);
1.1       root       21:        laddr = laddr_;
                     22:        paddr = (uint32)laddr;
                     23: 
1.1.1.4 ! root       24:        bus = md->GetBus();
        !            25:        lcol = md->GetLASize() / 4;
        !            26:        pcol = md->GetPASize() / 4;
        !            27: 
        !            28:        translate = false;
        !            29:        if (access_mode_ == MemoryMode::Logical) {
        !            30:                // lookup はここで enum から bool にしておく
        !            31:                lookup = static_cast<bool>(lookup_mode);
        !            32: 
        !            33:                if (md->MMUEnabled()) {
        !            34:                        translate = true;
        !            35:                        // FormatAddr() なしで Fetch/Peek を実行した場合でも、初回に
        !            36:                        // アドレス変換を起こさせるため。SetNBreakpoint() で使う。
        !            37:                        pageover = true;
        !            38:                }
1.1       root       39:        }
                     40: }
                     41: 
                     42: // 現在のアドレスを表示用に整形して str に代入する。
                     43: // アドレス変換でバスエラーが起きたら false を返す。
                     44: bool
                     45: DebuggerMemoryStream::FormatAddr(std::string& str)
                     46: {
                     47:        // ここは pageover に関係なく必ずアドレス変換を行う。
                     48:        // (その結果必ず pageover = false になる)
                     49: 
                     50:        if (translate) {
                     51:                // laddr は論理アドレスなのでアドレス変換する
                     52:                uint64 tmp = md->TranslateAddr(laddr, lookup);
                     53:                pageover = false;
                     54: 
                     55:                // laddr は常に表示
1.1.1.4 ! root       56:                str = strhex((uint32)laddr, lcol);
1.1       root       57: 
                     58:                if ((int64)tmp < 0) {
                     59:                        // アドレス変換の結果バスエラーなら false で帰る
                     60:                        str += ":BusErr";
                     61:                        return false;
                     62:                }
                     63: 
                     64:                paddr = (uint32)tmp;
                     65:                if (paddr == (uint32)laddr) {
                     66:                        // PA==VA
                     67:                        str += "=PA";
                     68:                } else {
                     69:                        // PA!=VA
1.1.1.4 ! root       70:                        str += ':';
        !            71:                        str += strhex(paddr, pcol);
        !            72:                        str += ':';
1.1       root       73:                }
                     74:        } else {
                     75:                // laddr は物理アドレスなのでそのまま
                     76:                paddr = (uint32)laddr;
                     77: 
1.1.1.4 ! root       78:                str = strhex(paddr, pcol);
        !            79:                str += ':';
1.1       root       80:        }
                     81: 
                     82:        return true;
                     83: }
                     84: 
1.1.1.4 ! root       85: // アドレスを進める(戻す)。
        !            86: void
        !            87: DebuggerMemoryStream::Offset(int n)
        !            88: {
        !            89:        ResetAddr(laddr.GetAddr() + n);
        !            90: }
        !            91: 
1.1       root       92: // アドレスをリセットする。
                     93: // (他のパラメータは維持するので、1ワード戻るとかそういう時用)
                     94: void
                     95: DebuggerMemoryStream::ResetAddr(uint32 newaddr)
                     96: {
                     97:        if (((newaddr ^ (uint32)laddr) & 0xffffff00) != 0) {
                     98:                pageover = true;
                     99:        }
                    100:        laddr = newaddr;
                    101:        paddr = newaddr;
                    102: }
                    103: 
                    104: // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。
                    105: #define PRECHECK() do {        \
                    106:        if (__predict_false(pageover)) {        \
                    107:                uint64 tmp = md->TranslateAddr(laddr, lookup);  \
                    108:                if ((int64)tmp < 0) {   \
                    109:                        return (uint64)-2;      \
                    110:                }       \
                    111:                paddr = (uint32)tmp;    \
                    112:                pageover = false;       \
                    113:        }       \
                    114: } while (0)
                    115: 
                    116: // 論理アドレスがページ境界をまたいだかどうか。
                    117: // m68k はページサイズが 256バイト..32KB まで可変だが、いつ変わるか
                    118: // 分からないページサイズマスクを取得することを考えたら、多少の無駄
                    119: // を承知で常に 256 バイトおきにチェックするほうがマシかもしれない。
                    120: #define POSTCHECK() do {       \
                    121:        if (__predict_false(translate && (paddr & 0xff) == 0)) {        \
                    122:                pageover = true;        \
                    123:        }       \
                    124: } while (0)
                    125: 
                    126: 
1.1.1.4 ! root      127: // laddr から指定バイト数を右詰めで読み込むが、アドレスは進めない。
1.1       root      128: uint64
1.1.1.4 ! root      129: DebuggerMemoryStream::Peek(int bytes)
1.1       root      130: {
                    131:        uint64 data;
                    132: 
1.1.1.4 ! root      133:        assert(((uint32)laddr & (bytes - 1)) == 0);
1.1       root      134: 
                    135:        PRECHECK();
                    136: 
                    137:        data = 0;
1.1.1.4 ! root      138:        for (int i = 0; i < bytes; i++) {
1.1       root      139:                data <<= 8;
1.1.1.4 ! root      140:                data |= bus->Peek8(paddr + i);
1.1       root      141:        }
                    142: 
                    143:        return data;
                    144: }
                    145: 
1.1.1.4 ! root      146: // laddr から指定バイト数を右詰めで読み込んで、アドレスを進める。
1.1       root      147: uint64
1.1.1.4 ! root      148: DebuggerMemoryStream::Read(int bytes)
1.1       root      149: {
                    150:        uint64 data;
                    151: 
1.1.1.4 ! root      152:        data = Peek(bytes);
        !           153:        laddr += bytes;
        !           154:        paddr += bytes;
1.1       root      155: 
                    156:        POSTCHECK();
                    157: 
                    158:        return data;
                    159: }
                    160: 
                    161: // laddr から1バイト読み込んで、アドレスを進める。
                    162: uint64
1.1.1.4 ! root      163: DebuggerMemoryStream::Read8()
1.1       root      164: {
                    165:        uint64 data;
                    166: 
                    167:        PRECHECK();
                    168: 
1.1.1.4 ! root      169:        data = bus->Peek8(paddr);
1.1       root      170:        laddr++;
                    171:        paddr++;
                    172: 
                    173:        POSTCHECK();
                    174: 
                    175:        return data;
                    176: }

unix.superglobalmegacorp.com

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