|
|
1.1 root 1: //
2: // nono
3: // Copyright (C) 2024 nono project
4: // Licensed under nono-license.txt
5: //
6:
7: //
8: // アクセス状況 (グラフィカル) ウィンドウ
9: //
10:
11: // パネルには WXTextScreen 同様に四辺に DefaultPadding を手動で入れてある。
12:
13: #include "wxaccstatmonitor.h"
14: #include "wxcolor.h"
15: #include "wxtextscreen.h"
16: #include "bankram.h"
1.1.1.2 root 17: #include "mainapp.h"
1.1 root 18: #include "mainbus.h"
1.1.1.2 root 19: #include "monitor.h"
1.1 root 20:
21: //
22: // アクセス状況 (グラフィカル) パネル
23: //
24:
25: // コンストラクタ
1.1.1.2 root 26: WXAccStatPanel::WXAccStatPanel(wxWindow *parent, Monitor *monitor_)
1.1 root 27: : inherited(parent, monitor_)
28: {
1.1.1.3 ! root 29: SetName("AccStatPanel");
! 30:
1.1 root 31: // デバイスを取得
32: mainbus = GetMainbusDevice();
33:
34: // バンクメモリ描画のため
35: is_x68030 = gMainApp.IsX68030();
36: if (is_x68030) {
37: for (int n = 0; n < 2; n++) {
38: auto bankdev = gMainApp.FindObject<BankRAMDevice>(OBJ_BANKRAM(n));
39: bankram[n] = (bankdev != NULL);
40: }
41: }
42:
43: FontChanged();
44: }
45:
46: // デストラクタ
47: WXAccStatPanel::~WXAccStatPanel()
48: {
49: }
50:
51: void
52: WXAccStatPanel::FontChanged()
53: {
54: inherited::FontChanged();
55:
1.1.1.2 root 56: auto monsz = mainbus->accstat_monitor->GetSize();
1.1 root 57: wxSize size(
58: WXTextScreen::DefaultPadding * 2 + monsz.width * font_width,
59: WXTextScreen::DefaultPadding * 2 + monsz.height * font_height);
60:
1.1.1.3 ! root 61: // バックバッファのサイズを固定。
! 62: SetMinBitmapSize(size);
! 63:
! 64: SetSize(size);
! 65: SetMinSize(size);
1.1 root 66:
67: redraw_header = true;
68: }
69:
70: void
71: WXAccStatPanel::Draw()
72: {
73: const int padding = WXTextScreen::DefaultPadding;
74: const auto& accstat_rw = mainbus->accstat_rw;
75: const auto& accstat_avail = mainbus->accstat_avail;
76: int rows = accstat_rw.size() / 64;
77: uint fw = font_width;
78: uint fh = font_height;
79:
80: // 8文字分(16MB) ごとに 0.5 文字分ずつ空ける
81: int width8 = fw * 8 + (fw / 2);
82:
83: if (redraw_header) {
84: redraw_header = false;
85:
86: char buf[80];
87: static_assert(AccStat::SHIFT >= 20, "");
88: snprintf(buf, sizeof(buf),
89: "Show %ubit space. %uMB/piece. ' ':Read, ' ':Write(+Read)",
90: mainbus->accstat_bitlen, 1U << (AccStat::SHIFT - 20));
91: DrawStringSJIS(padding, padding, buf);
92:
93: bitmap.FillRect(UD_GREEN, padding + fw * 30, padding, fw - 1, fh - 1);
94: bitmap.FillRect(UD_RED, padding + fw * 40, padding, fw - 1, fh - 1);
95:
96: for (uint i = 0; i < 8; i++) {
97: snprintf(buf, sizeof(buf), "+$0%x", i);
98: DrawStringSJIS(padding + fw * 12 + width8 * i,
99: padding + fh * 1, buf);
100: }
101:
102: uint baseaddr;
103: if (accstat_rw.size() == mainbus->accstat_read.size()) {
104: baseaddr = 0;
105: } else {
106: baseaddr = 0xc0;
107: }
108:
109: for (int y = 0; y < rows; y++) {
110: snprintf(buf, sizeof(buf), "$%02x00'0000:",
111: (uint8)(baseaddr + y * 0x08));
112: DrawStringSJIS(padding, padding + fh * (y + 2), buf);
113: }
114:
115: if (is_x68030) {
116: for (int n = 0; n < 2; n++) {
117: snprintf(buf, sizeof(buf), "BankMem #%u:", n);
118: DrawStringSJIS(padding, padding + fh * (35 + n), buf);
119: }
120: }
121: }
122:
123: // UD_{RED,GREEN} から UD_LIGHT_GREY まで HSV の S,V を線形補間。
124: static const Color cols[8] = {
125: UD_RED, // HSV(18, 100, 100)
126: UD_GREEN, // HSV(162, 98, 69)
127: Color(242, 115, 60), // HSV(18, 75, 95)
128: Color(47, 183, 142), // HSV(162, 74, 72)
129: Color(229, 149, 114), // HSV(18, 50, 90)
130: Color(97, 191, 163), // HSV(162, 49, 75)
131: Color(216, 178, 162), // HSV(18, 25, 85)
132: Color(149, 196, 182), // HSV(162, 24, 77)
133: };
134: // UD_LIGHT_GREY // HSV(240, 1, 80)
135:
136: uint py = padding + fh * 2;
137: for (int y = 0; y < rows; y++) {
138: const uint8 *a = &mainbus->accstat_rw[y * 64];
139: uint8 avail = accstat_avail[y];
140: uint px = padding + fw * 12;
141:
142: for (int i = 0; i < 8; i++) {
143: if ((int8)avail < 0) {
144: // 何かしらデバイスがある 16MB (8文字相当) 分。
145: for (int j = 0; j < 8; j++, a++, px += fw) {
146: uint8 op = *a;
147: Color c;
148: if (__predict_true(op == 0)) {
149: c = UD_LIGHT_GREY;
150: } else {
151: c = cols[__builtin_ctz(op)];
152: }
153: bitmap.DrawLineH(c, px, py, px + fw - 1);
154: }
155: } else {
156: // この 16MB には何のデバイスもない。
157: a += 8;
158: // 事故がなければこれなくても動くはず
159: //bitmap.DrawLineH(BGPANEL, px, py, px + fw * 8 - 1);
160: px += fw * 8;
161: }
162: avail <<= 1;
163: px += fw / 2;
164: }
165:
166: // 1ラスターを縦1文字分に展開
167: CopyLine(12, py, 68);
168: py += fh;
169: }
170:
171: // バンクメモリ
172: if (is_x68030) {
173: for (int n = 0; n < 2; n++) {
174: if (bankram[n]) {
175: py = padding + fh * (35 + n);
176: const uint8 *a = &mainbus->accbank[n * AccStat::BANKLEN];
177: uint px = padding + fw * 12;
178:
179: for (int j = 0; j < 8; j++, a++, px += fw) {
180: uint8 op = *a;
181: Color c;
182: if (__predict_true(op == 0)) {
183: c = UD_LIGHT_GREY;
184: } else {
185: c = cols[__builtin_ctz(op)];
186: }
187: bitmap.DrawLineH(c, px, py, px + fw - 1);
188: }
189:
190: // 1ラスターを縦1文字分に展開
191: CopyLine(12, py, 8);
192: }
193: }
194: }
195: }
196:
197: // 1ラスターを縦1文字分に展開する。
198: // ただの共通下請けなので引数に汎用性はない。
199: // cx は文字単位の X 座標 (左端の1文字目が 0、次の文字が 1)。
200: // py はピクセル単位の Y 座標。
201: // clen はコピーする文字数。
202: // (cxをピクセルにした座標, py) から clen 文字分の長さを次ラスターから
203: // (font_height - 1) ラスターまでにコピーする。
204: void
205: WXAccStatPanel::CopyLine(int cx, int py, int clen)
206: {
207: const int padding = WXTextScreen::DefaultPadding;
208: int px = padding + font_width * cx;
209: Rect rect(px, py, clen * font_width, font_height - 1);
210:
211: bitmap.CopyFromTop(rect);
212: }
213:
214:
215: //
216: // アクセス状況 (グラフィカル) ウィンドウ
217: //
218:
219: // コンストラクタ
1.1.1.2 root 220: WXAccStatWindow::WXAccStatWindow(wxWindow *parent, Monitor *monitor_)
1.1 root 221: : inherited(parent, wxID_ANY, _("Access Status"))
222: {
223: new WXAccStatPanel(this, monitor_);
1.1.1.3 ! root 224: Fit();
1.1 root 225: }
226:
227: // デストラクタ
228: WXAccStatWindow::~WXAccStatWindow()
229: {
230: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.