|
|
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: };
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.