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

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

unix.superglobalmegacorp.com

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