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