Annotation of nono/vm/iodevstream.h, revision 1.1.1.7

1.1       root        1: //
                      2: // nono
1.1.1.2   root        3: // Copyright (C) 2020 nono project
                      4: // Licensed under nono-license.txt
1.1       root        5: //
                      6: 
                      7: #pragma once
                      8: 
                      9: #include "device.h"
                     10: 
                     11: // IODevice クラスへの Read/Write をストリームっぽく扱う。
                     12: // Read/Write とも受け渡しはホストバイトオーダの値で行い、
                     13: // デバイスへのアクセスはビッグエンディアンで行う。
                     14: // アクセス中にバスエラーが起きることは考慮していない。
1.1.1.7 ! root       15: //
        !            16: // addr は基本的には物理アドレスだが、Read()/Write() がアドレスをマスクする
        !            17: // タイプならオフセットを指定しても等価となる。
        !            18: // MainRAM は物理アドレスだが、通常 0 から始まるのでどちらも等価にみえる。
        !            19: // ExtRAM なら物理アドレスでなければならない。
        !            20: // SubRAM はアドレスをマスクするので、アドレスでもオフセットでもよいが
        !            21: // XP 視点でいえばオフセットのほうが処理しやすい、などそれぞれ事情が異なる。
        !            22: // 指定したデバイスがどっちの振る舞いなのかは把握してから使うこと。
        !            23: // どちらにしてもこのクラスでは "アドレス" と呼ぶ。
1.1       root       24: class IODeviceStream
                     25: {
                     26:  public:
                     27:        // コンストラクタ
1.1.1.5   root       28:        explicit IODeviceStream(IODevice *dev_) {
                     29:                dev = dev_;
1.1       root       30:        }
1.1.1.7 ! root       31:        IODeviceStream(IODevice *dev_, uint32 addr_) {
1.1.1.5   root       32:                dev = dev_;
1.1.1.7 ! root       33:                addr = addr_;
1.1       root       34:        }
1.1.1.5   root       35:        ~IODeviceStream();
1.1       root       36: 
                     37:        // アドレスを設定する
1.1.1.7 ! root       38:        void SetAddr(uint32 addr_) {
        !            39:                addr = addr_;
1.1       root       40:        }
                     41:        // アドレスを取得する
1.1.1.7 ! root       42:        uint32 GetAddr() const {
        !            43:                return addr;
1.1       root       44:        }
                     45: 
                     46:        // 1バイト読み込んでポインタを進める
1.1.1.5   root       47:        uint64 Read1() {
                     48:                return ReadN(BusAddr::Size1);
1.1       root       49:        }
                     50: 
                     51:        // 2バイト読み込んでポインタを進める。addr はアラインしなくてよい
1.1.1.5   root       52:        uint64 Read2() {
                     53:                return ReadN(BusAddr::Size2);
1.1       root       54:        }
                     55: 
                     56:        // 4バイト読み込んでポインタを進める。addr はアラインしなくてよい
                     57:        // データはホストエンディアンで返される。
1.1.1.5   root       58:        uint64 Read4() {
                     59:                return ReadN(BusAddr::Size4);
1.1       root       60:        }
                     61: 
                     62:        // 1バイト書き込んでポインタを進める
1.1.1.5   root       63:        void Write1(uint32 data)
1.1       root       64:        {
1.1.1.5   root       65:                WriteN(BusAddr::Size1, data);
1.1       root       66:        }
                     67: 
                     68:        // 2バイト書き込んでポインタを進める。addr はアラインしてなくてよい
1.1.1.5   root       69:        void Write2(uint32 data)
1.1       root       70:        {
1.1.1.5   root       71:                WriteN(BusAddr::Size2, data);
1.1       root       72:        }
                     73: 
1.1.1.6   root       74:        // 3バイト書き込んでポインタを進める。addr はアラインしてなくてよい
                     75:        void Write3(uint32 data)
                     76:        {
                     77:                WriteN(BusAddr::Size3, data);
                     78:        }
                     79: 
1.1       root       80:        // 4バイト書き込んでポインタを進める。addr はアラインしてなくてよい
1.1.1.5   root       81:        void Write4(uint32 data)
1.1       root       82:        {
1.1.1.5   root       83:                WriteN(BusAddr::Size4, data);
1.1       root       84:        }
                     85: 
1.1.1.4   root       86:        // LE で2バイト書き込んでポインタを進める。addr はアラインしてなくてよい
1.1.1.5   root       87:        void Write2LE(uint32 data)
1.1.1.4   root       88:        {
1.1.1.5   root       89:                Write1(data & 0xff);
                     90:                Write1(data >> 8);
1.1.1.4   root       91:        }
                     92: 
                     93:        // 文字列を書き込んでポインタを進める。
                     94:        void WriteString(const char *p)
                     95:        {
                     96:                while (*p) {
1.1.1.5   root       97:                        Write1(*p++);
1.1.1.4   root       98:                }
1.1.1.5   root       99:                Write1('\0');
1.1.1.4   root      100:        }
                    101: 
1.1.1.5   root      102:        // ホストの src から len バイトを書き込んでポインタを進める。
                    103:        void WriteMem(const void *src, uint len);
                    104: 
1.1       root      105:        // アドレスも指定する版。ポインタは同様に進める
1.1.1.7 ! root      106:        uint64 Read1(uint32 addr_) {
        !           107:                SetAddr(addr_);
1.1.1.5   root      108:                return Read1();
                    109:        }
1.1.1.7 ! root      110:        uint64 Read2(uint32 addr_) {
        !           111:                SetAddr(addr_);
1.1.1.5   root      112:                return Read2();
                    113:        }
1.1.1.7 ! root      114:        uint64 Read4(uint32 addr_) {
        !           115:                SetAddr(addr_);
1.1.1.5   root      116:                return Read4();
                    117:        }
1.1.1.7 ! root      118:        void Write1(uint32 addr_, uint32 data) {
        !           119:                SetAddr(addr_);
1.1.1.5   root      120:                Write1(data);
                    121:        }
1.1.1.7 ! root      122:        void Write2(uint32 addr_, uint32 data) {
        !           123:                SetAddr(addr_);
1.1.1.5   root      124:                Write2(data);
                    125:        }
1.1.1.7 ! root      126:        void Write4(uint32 addr_, uint32 data) {
        !           127:                SetAddr(addr_);
1.1.1.5   root      128:                Write4(data);
1.1       root      129:        }
                    130: 
                    131:  private:
1.1.1.5   root      132:        busdata ReadN(busaddr size);
                    133:        busdata WriteN(busaddr size, uint32 data);
                    134: 
1.1.1.3   root      135:        IODevice *dev {};
1.1.1.7 ! root      136:        uint32 addr {};
1.1       root      137: };

unix.superglobalmegacorp.com

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