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