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

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.5 ! root       99:        if (((newaddr ^ laddr.Addr()) & 0xffffff00) != 0) {
1.1       root      100:                pageover = true;
                    101:        }
1.1.1.5 ! root      102:        laddr.SetAddr(newaddr);
1.1       root      103:        paddr = newaddr;
                    104: }
                    105: 
                    106: // 前回のアクセスでページ境界をまたいだかも知れない場合は再変換。
                    107: #define PRECHECK() do {        \
                    108:        if (__predict_false(pageover)) {        \
1.1.1.5 ! root      109:                busaddr tmp = md->TranslateAddr(laddr); \
        !           110:                if (__predict_false(tmp.IsBusErr())) {  \
1.1       root      111:                        return (uint64)-2;      \
                    112:                }       \
1.1.1.5 ! root      113:                paddr = tmp.Addr();     \
1.1       root      114:                pageover = false;       \
                    115:        }       \
                    116: } while (0)
                    117: 
                    118: // 論理アドレスがページ境界をまたいだかどうか。
                    119: // m68k はページサイズが 256バイト..32KB まで可変だが、いつ変わるか
                    120: // 分からないページサイズマスクを取得することを考えたら、多少の無駄
                    121: // を承知で常に 256 バイトおきにチェックするほうがマシかもしれない。
                    122: #define POSTCHECK() do {       \
                    123:        if (__predict_false(translate && (paddr & 0xff) == 0)) {        \
                    124:                pageover = true;        \
                    125:        }       \
                    126: } while (0)
                    127: 
                    128: 
1.1.1.4   root      129: // laddr から指定バイト数を右詰めで読み込むが、アドレスは進めない。
1.1       root      130: uint64
1.1.1.4   root      131: DebuggerMemoryStream::Peek(int bytes)
1.1       root      132: {
                    133:        uint64 data;
                    134: 
1.1.1.5 ! root      135:        assert((laddr & (bytes - 1)) == 0);
1.1       root      136: 
                    137:        PRECHECK();
                    138: 
                    139:        data = 0;
1.1.1.4   root      140:        for (int i = 0; i < bytes; i++) {
1.1.1.5 ! root      141:                busdata bd = bus->Peek8(paddr + i);
        !           142:                if (__predict_false(bd.IsBusErr())) {
        !           143:                        return bd;
        !           144:                }
        !           145:                data = (data << 8) | bd.Data();
1.1       root      146:        }
                    147: 
                    148:        return data;
                    149: }
                    150: 
1.1.1.4   root      151: // laddr から指定バイト数を右詰めで読み込んで、アドレスを進める。
1.1       root      152: uint64
1.1.1.4   root      153: DebuggerMemoryStream::Read(int bytes)
1.1       root      154: {
                    155:        uint64 data;
                    156: 
1.1.1.4   root      157:        data = Peek(bytes);
                    158:        laddr += bytes;
                    159:        paddr += bytes;
1.1       root      160: 
                    161:        POSTCHECK();
                    162: 
                    163:        return data;
                    164: }
                    165: 
                    166: // laddr から1バイト読み込んで、アドレスを進める。
                    167: uint64
1.1.1.4   root      168: DebuggerMemoryStream::Read8()
1.1       root      169: {
                    170:        uint64 data;
                    171: 
                    172:        PRECHECK();
                    173: 
1.1.1.4   root      174:        data = bus->Peek8(paddr);
1.1.1.5 ! root      175:        ++laddr;
        !           176:        ++paddr;
1.1       root      177: 
                    178:        POSTCHECK();
                    179: 
                    180:        return data;
                    181: }

unix.superglobalmegacorp.com

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