ProgramFlowVisualizer.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48: package xeij;
49:
50: import java.awt.*;
51: import java.awt.event.*;
52: import java.awt.image.*;
53: import java.lang.*;
54: import java.util.*;
55: import javax.swing.*;
56:
57: public class ProgramFlowVisualizer {
58:
59: public static final boolean PFV_ON = true;
60:
61:
62: public static final int PFV_LOG2_BYTES_PER_CELL = 5;
63: public static final int PFV_LOG2_CELLS_PER_LINE = 8;
64: public static final int PFV_LOG2_BYTES_PER_LINE = PFV_LOG2_BYTES_PER_CELL + PFV_LOG2_CELLS_PER_LINE;
65: public static final int PFV_LOG2_TOTAL_LINES = 32 - PFV_LOG2_BYTES_PER_LINE;
66: public static final int PFV_BYTES_PER_CELL = 1 << PFV_LOG2_BYTES_PER_CELL;
67: public static final int PFV_CELLS_PER_LINE = 1 << PFV_LOG2_CELLS_PER_LINE;
68: public static final int PFV_BYTES_PER_LINE = 1 << PFV_LOG2_BYTES_PER_LINE;
69: public static final int PFV_TOTAL_LINES = 1 << PFV_LOG2_TOTAL_LINES;
70:
71: public static final int PFV_MARGIN_LEFT = 2;
72: public static final int PFV_ADDRESS1_WIDTH = 34;
73: public static final int PFV_BAR_WIDTH = 10;
74: public static final int PFV_FUNNEL_WIDTH = 8;
75: public static final int PFV_ADDRESS2_WIDTH = 34;
76: public static final int PFV_MAP_WIDTH = PFV_CELLS_PER_LINE << 1;
77: public static final int PFV_MARGIN_RIGHT = 2;
78:
79: public static final int PFV_ADDRESS1_X0 = PFV_MARGIN_LEFT;
80: public static final int PFV_BAR_X0 = PFV_ADDRESS1_X0 + PFV_ADDRESS1_WIDTH;
81: public static final int PFV_FUNNEL_X0 = PFV_BAR_X0 + PFV_BAR_WIDTH;
82: public static final int PFV_ADDRESS2_X0 = PFV_FUNNEL_X0 + PFV_FUNNEL_WIDTH;
83: public static final int PFV_MAP_X0 = PFV_ADDRESS2_X0 + PFV_ADDRESS2_WIDTH;
84: public static final int PFV_PANEL_WIDTH = PFV_MAP_X0 + PFV_MAP_WIDTH + PFV_MARGIN_RIGHT;
85:
86: public static final int PFV_MARGIN_TOP = 2;
87: public static final int PFV_OFFSET_HEIGHT = 6 + 2;
88: public static final int PFV_MAP_MIN_HEIGHT = 128;
89: public static final int PFV_MAP_DEFAULT_HEIGHT = 256;
90: public static final int PFV_MARGIN_BOTTOM = 2;
91:
92: public static final int PFV_OFFSET_Y0 = PFV_MARGIN_TOP;
93: public static final int PFV_MAP_Y0 = PFV_OFFSET_Y0 + PFV_OFFSET_HEIGHT;
94: public static final int PFV_PANEL_MIN_HEIGHT = PFV_MAP_Y0 + PFV_MAP_MIN_HEIGHT + PFV_MARGIN_BOTTOM;
95: public static final int PFV_PANEL_DEFAULT_HEIGHT = PFV_MAP_Y0 + PFV_MAP_DEFAULT_HEIGHT + PFV_MARGIN_BOTTOM;
96:
97: public static final int PFV_PANEL_MAX_HEIGHT = 1024;
98:
99: public static int pfvPanelHeight;
100: public static int pfvMapHeight;
101: public static int pfvMapY1;
102: public static int pfvLines;
103:
104:
105: public static int pfvLine0;
106: public static int pfvLine1;
107: public static int pfvAddress0;
108: public static int pfvAddress1;
109: public static int pfvFunnelY0;
110: public static int pfvFunnelY1;
111: public static int pfvPressedX;
112: public static int pfvPressedY;
113: public static int pfvPressedLine0;
114: public static int pfvSpan;
115:
116:
117:
118:
119: public static final float PFV_COLOR_H0 = 4F / 6F;
120: public static final float PFV_COLOR_H1 = 7F / 6F;
121: public static final float PFV_COLOR_S0 = 1F;
122: public static final float PFV_COLOR_S1 = 1F;
123: public static final float PFV_COLOR_B0 = 0.2F;
124: public static final float PFV_COLOR_B1 = 1F;
125: public static final int PFV_ADDRESS_PALET = 240;
126: public static final int PFV_FUNNEL_PALET = 240;
127:
128:
129: public static BufferedImage pfvImage;
130: public static byte[] pfvBitmap;
131: public static JPanel pfvPanel;
132: public static JFrame pfvFrame;
133:
134:
135: public static final int PFV_INTERVAL = 10;
136: public static int pfvTimer;
137:
138:
139:
140: public static void pfvInit () {
141:
142: pfvPanelHeight = PFV_PANEL_DEFAULT_HEIGHT;
143: pfvMapHeight = PFV_MAP_DEFAULT_HEIGHT;
144: pfvMapY1 = PFV_MAP_Y0 - 1 + pfvMapHeight;
145: pfvLines = pfvMapHeight + 1 >>> 1;
146:
147: pfvLine0 = 0;
148: pfvLine1 = pfvLine0 + pfvLines - 1;
149: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
150: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
151: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
152: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
153: pfvPressedX = -1;
154:
155:
156: pfvSpan = 8;
157:
158: byte[] red = new byte[256];
159: byte[] green = new byte[256];
160: byte[] blue = new byte[256];
161: for (int i = 0; i < 256; i++) {
162: int rgb = Color.HSBtoRGB (PFV_COLOR_H0 + i * (1F / 256F * (PFV_COLOR_H1 - PFV_COLOR_H0)),
163: PFV_COLOR_S0 + i * (1F / 256F * (PFV_COLOR_S1 - PFV_COLOR_S0)),
164: PFV_COLOR_B0 + i * (1F / 256F * (PFV_COLOR_B1 - PFV_COLOR_B0)));
165: red[i] = (byte) (rgb >>> 16);
166: green[i] = (byte) (rgb >>> 8);
167: blue[i] = (byte) rgb;
168: }
169: IndexColorModel icm = new IndexColorModel (8, 256, red, green, blue);
170:
171: pfvImage = new BufferedImage (PFV_PANEL_WIDTH, PFV_PANEL_MAX_HEIGHT, BufferedImage.TYPE_BYTE_INDEXED, icm);
172: pfvBitmap = ((DataBufferByte) pfvImage.getRaster ().getDataBuffer ()).getData ();
173: pfvPanel = null;
174: pfvFrame = null;
175:
176: pfvTimer = 0;
177: }
178:
179:
180: public static void pfvStart () {
181: if (RestorableFrame.rfmGetOpened (Settings.SGS_PFV_FRAME_KEY)) {
182: pfvOpen ();
183: }
184: }
185:
186:
187:
188: public static void pfvOpen () {
189: if (pfvFrame == null) {
190: pfvMakeFrame ();
191: }
192: XEiJ.dbgVisibleMask |= XEiJ.DBG_PFV_VISIBLE_MASK;
193: if (XEiJ.mpuTask == null) {
194: pfvUpdate ();
195: }
196: pfvFrame.setVisible (true);
197: }
198:
199:
200:
201:
202: public static void pfvMakeFrame () {
203:
204: pfvPanel = ComponentFactory.setMinimumSize (
205: ComponentFactory.setPreferredSize (
206: ComponentFactory.setMaximumSize (
207: new JPanel () {
208: @Override public void paint (Graphics g) {
209: g.drawImage (pfvImage, 0, 0, null);
210: }
211: @Override protected void paintComponent (Graphics g) {
212: }
213: @Override protected void paintBorder (Graphics g) {
214: }
215: @Override protected void paintChildren (Graphics g) {
216: }
217: @Override public void update (Graphics g) {
218: }
219: },
220: PFV_PANEL_WIDTH, PFV_PANEL_MAX_HEIGHT),
221: PFV_PANEL_WIDTH, PFV_PANEL_DEFAULT_HEIGHT),
222: PFV_PANEL_WIDTH, PFV_PANEL_MIN_HEIGHT);
223:
224: ComponentFactory.addListener (
225: pfvPanel,
226: new ComponentAdapter () {
227: @Override public void componentResized (ComponentEvent ce) {
228: pfvPanelHeight = Math.max (PFV_PANEL_MIN_HEIGHT, Math.min (PFV_PANEL_MAX_HEIGHT, pfvPanel.getHeight ()));
229: pfvMapHeight = pfvPanelHeight - (PFV_MARGIN_TOP + PFV_MARGIN_BOTTOM);
230: pfvMapY1 = PFV_MAP_Y0 - 1 + pfvMapHeight;
231: pfvLines = pfvMapHeight + 1 >> 1;
232: pfvLine0 = Math.max (0, Math.min (PFV_TOTAL_LINES - pfvLines, pfvLine0 + pfvLine1 + 1 - pfvLines >> 1));
233: pfvLine1 = pfvLine0 + pfvLines - 1;
234: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
235: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
236: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
237: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
238: if (XEiJ.mpuTask == null) {
239: pfvUpdate ();
240: }
241: }
242: });
243:
244: pfvPanel.setFocusable (true);
245: ComponentFactory.addListener (
246: pfvPanel,
247: new KeyAdapter () {
248: @Override public void keyPressed (KeyEvent ke) {
249: int line0;
250: switch (ke.getKeyCode ()) {
251: case KeyEvent.VK_UP:
252: line0 = pfvLine0 - 16;
253: break;
254: case KeyEvent.VK_DOWN:
255: line0 = pfvLine0 + 16;
256: break;
257: case KeyEvent.VK_PAGE_UP:
258: line0 = pfvLine0 - (pfvLines * 15 >> 4);
259: break;
260: case KeyEvent.VK_PAGE_DOWN:
261: line0 = pfvLine0 + (pfvLines * 15 >> 4);
262: break;
263: default:
264: return;
265: }
266: pfvLine0 = Math.max (0, Math.min (PFV_TOTAL_LINES - pfvLines, line0));
267: pfvLine1 = pfvLine0 + pfvLines - 1;
268: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
269: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
270: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
271: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
272: if (XEiJ.mpuTask == null) {
273: pfvUpdate ();
274: }
275: }
276: });
277:
278: ComponentFactory.addListener (
279: pfvPanel,
280: new MouseAdapter () {
281: @Override public void mouseClicked (MouseEvent me) {
282: int x = me.getX ();
283: int y = me.getY ();
284: if (PFV_MAP_X0 <= x && x < PFV_MAP_X0 + PFV_MAP_WIDTH && PFV_MAP_Y0 <= y && y <= pfvMapY1) {
285:
286: DisassembleList.ddpOpen (pfvAddress0 + (x - PFV_MAP_X0 >> 1 << PFV_LOG2_BYTES_PER_CELL) + (y - PFV_MAP_Y0 >> 1 << PFV_LOG2_BYTES_PER_LINE), XEiJ.regSRS, false);
287: }
288: }
289: @Override public void mouseExited (MouseEvent me) {
290: pfvPressedX = -1;
291: }
292: @Override public void mousePressed (MouseEvent me) {
293: int x = me.getX ();
294: int y = me.getY ();
295: if (PFV_BAR_X0 <= x && x < PFV_ADDRESS2_X0) {
296: pfvLine0 = Math.max (0, Math.min (PFV_TOTAL_LINES - pfvLines, (int) ((long) PFV_TOTAL_LINES * (y - PFV_MAP_Y0) / pfvMapHeight) - (pfvLines >> 1)));
297: pfvLine1 = pfvLine0 + pfvLines - 1;
298: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
299: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
300: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
301: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
302: if (XEiJ.mpuTask == null) {
303: pfvUpdate ();
304: }
305: }
306: pfvPressedX = x;
307: pfvPressedY = y;
308: pfvPressedLine0 = pfvLine0;
309: }
310: @Override public void mouseReleased (MouseEvent me) {
311: pfvPressedX = -1;
312: }
313: });
314:
315: ComponentFactory.addListener (
316: pfvPanel,
317: new MouseMotionAdapter () {
318: @Override public void mouseDragged (MouseEvent me) {
319: if (pfvPressedX >= 0) {
320: int x = me.getX ();
321: int y = me.getY ();
322: pfvLine0 = Math.max (0, Math.min (PFV_TOTAL_LINES - pfvLines,
323: PFV_BAR_X0 <= x && pfvPressedX < PFV_ADDRESS2_X0 ?
324: (int) ((long) PFV_TOTAL_LINES * (y - PFV_MAP_Y0) / pfvMapHeight) - (pfvLines >> 1) :
325: pfvPressedLine0 - (y - pfvPressedY >> 1)));
326: pfvLine1 = pfvLine0 + pfvLines - 1;
327: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
328: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
329: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
330: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
331: if (XEiJ.mpuTask == null) {
332: pfvUpdate ();
333: }
334: }
335: }
336: });
337:
338: ComponentFactory.addListener (
339: pfvPanel,
340: new MouseWheelListener () {
341: @Override public void mouseWheelMoved (MouseWheelEvent mwe) {
342: pfvLine0 = Math.max (0, Math.min (PFV_TOTAL_LINES - pfvLines, pfvLine0 + (mwe.getWheelRotation () << 4)));
343: pfvLine1 = pfvLine0 + pfvLines - 1;
344: pfvAddress0 = pfvLine0 << PFV_LOG2_BYTES_PER_LINE;
345: pfvAddress1 = (pfvLine1 + 1 << PFV_LOG2_BYTES_PER_LINE) - 2;
346: pfvFunnelY0 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine0 / PFV_TOTAL_LINES);
347: pfvFunnelY1 = PFV_MAP_Y0 + (int) ((long) pfvMapHeight * pfvLine1 / PFV_TOTAL_LINES);
348: if (XEiJ.mpuTask == null) {
349: pfvUpdate ();
350: }
351: }
352: });
353:
354: ActionListener listener = new ActionListener () {
355: @Override public void actionPerformed (ActionEvent ae) {
356: Object source = ae.getSource ();
357: switch (ae.getActionCommand ()) {
358: case "Clear":
359: if (XEiJ.mpuTask == null) {
360: BranchLog.blgReset ();
361: BranchLog.blgArray[0] = XEiJ.regPC | XEiJ.regSRS >>> 13;
362: BranchLog.blgArray[1] = XEiJ.regPC;
363: pfvUpdate ();
364: }
365: break;
366: case "256 records":
367: pfvSpan = 0;
368: if (XEiJ.mpuTask == null) {
369: pfvUpdate ();
370: }
371: break;
372: case "512 records":
373: pfvSpan = 1;
374: if (XEiJ.mpuTask == null) {
375: pfvUpdate ();
376: }
377: break;
378: case "1024 records":
379: pfvSpan = 2;
380: if (XEiJ.mpuTask == null) {
381: pfvUpdate ();
382: }
383: break;
384: case "2048 records":
385: pfvSpan = 3;
386: if (XEiJ.mpuTask == null) {
387: pfvUpdate ();
388: }
389: break;
390: case "4096 records":
391: pfvSpan = 4;
392: if (XEiJ.mpuTask == null) {
393: pfvUpdate ();
394: }
395: break;
396: case "8192 records":
397: pfvSpan = 5;
398: if (XEiJ.mpuTask == null) {
399: pfvUpdate ();
400: }
401: break;
402: case "16384 records":
403: pfvSpan = 6;
404: if (XEiJ.mpuTask == null) {
405: pfvUpdate ();
406: }
407: break;
408: case "32768 records":
409: pfvSpan = 7;
410: if (XEiJ.mpuTask == null) {
411: pfvUpdate ();
412: }
413: break;
414: case "65536 records":
415: pfvSpan = 8;
416: if (XEiJ.mpuTask == null) {
417: pfvUpdate ();
418: }
419: break;
420: }
421: }
422: };
423:
424: ButtonGroup spanGroup = new ButtonGroup ();
425: pfvFrame = Multilingual.mlnTitle (
426: ComponentFactory.createRestorableSubFrame (
427: Settings.SGS_PFV_FRAME_KEY,
428: "Program flow visualizer",
429: null,
430: ComponentFactory.createBorderPanel (
431:
432: pfvPanel,
433:
434: ComponentFactory.createHorizontalBox (
435: XEiJ.mpuAddButtonStopped (
436: Multilingual.mlnToolTipText (
437: ComponentFactory.createImageButton (
438: LnF.LNF_CLEAR_IMAGE,
439: LnF.LNF_CLEAR_DISABLED_IMAGE,
440: "Clear", listener),
441: "ja", "クリア")
442: ),
443: Box.createHorizontalGlue (),
444: Multilingual.mlnToolTipText (
445: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 0,
446: LnF.LNF_NUMBER_IMAGE_ARRAY[0], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[0],
447: "256 records", listener),
448: "ja", "256 レコード"),
449: Multilingual.mlnToolTipText (
450: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 1,
451: LnF.LNF_NUMBER_IMAGE_ARRAY[1], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[1],
452: "512 records", listener),
453: "ja", "512 レコード"),
454: Multilingual.mlnToolTipText (
455: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 2,
456: LnF.LNF_NUMBER_IMAGE_ARRAY[2], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[2],
457: "1024 records", listener),
458: "ja", "1024 レコード"),
459: Multilingual.mlnToolTipText (
460: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 3,
461: LnF.LNF_NUMBER_IMAGE_ARRAY[3], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[3],
462: "2048 records", listener),
463: "ja", "2048 レコード"),
464: Multilingual.mlnToolTipText (
465: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 4,
466: LnF.LNF_NUMBER_IMAGE_ARRAY[4], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[4],
467: "4096 records", listener),
468: "ja", "4096 レコード"),
469: Multilingual.mlnToolTipText (
470: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 5,
471: LnF.LNF_NUMBER_IMAGE_ARRAY[5], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[5],
472: "8192 records", listener),
473: "ja", "8192 レコード"),
474: Multilingual.mlnToolTipText (
475: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 6,
476: LnF.LNF_NUMBER_IMAGE_ARRAY[6], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[6],
477: "16384 records", listener),
478: "ja", "16384 レコード"),
479: Multilingual.mlnToolTipText (
480: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 7,
481: LnF.LNF_NUMBER_IMAGE_ARRAY[7], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[7],
482: "32768 records", listener),
483: "ja", "32768 レコード"),
484: Multilingual.mlnToolTipText (
485: ComponentFactory.createIconRadioButton (spanGroup, pfvSpan == 8,
486: LnF.LNF_NUMBER_IMAGE_ARRAY[8], LnF.LNF_NUMBER_SELECTED_IMAGE_ARRAY[8],
487: "65536 records", listener),
488: "ja", "65536 レコード"),
489: Box.createHorizontalGlue (),
490: XEiJ.mpuMakeBreakButton (),
491: XEiJ.mpuMakeTraceButton (),
492: XEiJ.mpuMakeTrace10Button (),
493: XEiJ.mpuMakeTrace100Button (),
494: XEiJ.mpuMakeStepButton (),
495: XEiJ.mpuMakeStep10Button (),
496: XEiJ.mpuMakeStep100Button (),
497: XEiJ.mpuMakeReturnButton (),
498: XEiJ.mpuMakeRunButton ()
499: )
500: )
501: ),
502: "ja", "プログラムフロービジュアライザ");
503:
504: ComponentFactory.addListener (
505: pfvFrame,
506: new WindowAdapter () {
507: @Override public void windowClosing (WindowEvent we) {
508: XEiJ.dbgVisibleMask &= ~XEiJ.DBG_PFV_VISIBLE_MASK;
509: }
510: });
511: }
512:
513:
514:
515: public static void pfvUpdate () {
516: if (BranchLog.blgLock) {
517: return;
518: }
519: BranchLog.blgLock = true;
520: BranchLog.blgStop ();
521: Arrays.fill (pfvBitmap, 0, PFV_PANEL_WIDTH * pfvPanelHeight, (byte) 0);
522:
523: {
524: int sbits = 32 - 27 + Integer.numberOfLeadingZeros (pfvMapHeight);
525: int xbasemax = 1 << 32 - sbits;
526: for (int xbase = 0; xbase < xbasemax; xbase++) {
527: int x = xbase << sbits;
528: int i = PFV_PANEL_WIDTH * (PFV_MAP_Y0 - 2) + PFV_ADDRESS1_X0 + PFV_PANEL_WIDTH * (int) ((long) pfvMapHeight * (x & 0xffffffffL) >>> 32);
529: int t = x >>> 28;
530: pfvPutc ( i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
531: t = x >>> 24 & 15;
532: pfvPutc (4 * 1 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
533: t = x >>> 20 & 15;
534: pfvPutc (4 * 2 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
535: t = x >>> 16 & 15;
536: pfvPutc (4 * 3 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
537: t = (char) x >>> 12;
538: pfvPutc (4 * 4 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
539: t = x >>> 8 & 15;
540: pfvPutc (4 * 5 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
541: t = x >>> 4 & 15;
542: pfvPutc (4 * 6 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
543: t = x & 15;
544: pfvPutc (4 * 7 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
545: }
546: }
547:
548: {
549: int i = PFV_PANEL_WIDTH * PFV_MAP_Y0 + PFV_FUNNEL_X0 + (PFV_FUNNEL_WIDTH >>> 1);
550: pfvBitmap[i] =
551: pfvBitmap[i + 1] =
552: pfvBitmap[i + 2] =
553: pfvBitmap[i + 3] = (byte) PFV_FUNNEL_PALET;
554: for (int y = PFV_MAP_Y0; y < pfvFunnelY0; y++) {
555: pfvBitmap[i] = (byte) PFV_FUNNEL_PALET;
556: i += PFV_PANEL_WIDTH;
557: }
558: pfvBitmap[i - 3] =
559: pfvBitmap[i - 2] =
560: pfvBitmap[i - 1] =
561: pfvBitmap[i] = (byte) PFV_FUNNEL_PALET;
562: i += PFV_PANEL_WIDTH * (pfvFunnelY1 - pfvFunnelY0);
563: pfvBitmap[i - 3] =
564: pfvBitmap[i - 2] =
565: pfvBitmap[i - 1] =
566: pfvBitmap[i] = (byte) PFV_FUNNEL_PALET;
567: for (int y = pfvFunnelY1; y < pfvMapY1; y++) {
568: pfvBitmap[i] = (byte) PFV_FUNNEL_PALET;
569: i += PFV_PANEL_WIDTH;
570: }
571: pfvBitmap[i] =
572: pfvBitmap[i + 1] =
573: pfvBitmap[i + 2] =
574: pfvBitmap[i + 3] = (byte) PFV_FUNNEL_PALET;
575: }
576:
577: {
578: final int s = 4096 << PFV_LOG2_BYTES_PER_CELL - 1;
579: int x0 = pfvAddress0 + s - 1 & -s;
580: int xo1 = pfvAddress1 - x0;
581: for (int xo = 0; xo <= xo1; xo += s) {
582: int x = x0 + xo;
583: int i = PFV_PANEL_WIDTH * (PFV_MAP_Y0 - 2) + PFV_ADDRESS2_X0 + PFV_PANEL_WIDTH * (x - pfvAddress0 >>> PFV_LOG2_BYTES_PER_LINE - 1);
584: int t = x >>> 28;
585: pfvPutc ( i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
586: t = x >>> 24 & 15;
587: pfvPutc (4 * 1 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
588: t = x >>> 20 & 15;
589: pfvPutc (4 * 2 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
590: t = x >>> 16 & 15;
591: pfvPutc (4 * 3 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
592: t = (char) x >>> 12;
593: pfvPutc (4 * 4 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
594: t = x >>> 8 & 15;
595: pfvPutc (4 * 5 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
596: t = x >>> 4 & 15;
597: pfvPutc (4 * 6 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
598: t = x & 15;
599: pfvPutc (4 * 7 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
600: }
601: }
602:
603: {
604: final int s = 16 << PFV_LOG2_BYTES_PER_CELL - 1;
605: int y = PFV_OFFSET_Y0 + 2;
606: for (int x = 0; x < PFV_BYTES_PER_LINE; x += s) {
607: y = PFV_OFFSET_Y0 + PFV_OFFSET_Y0 + 2 - y;
608: if (x < 0x10) {
609: int i = PFV_PANEL_WIDTH * y + PFV_MAP_X0 - 1 + (x >>> PFV_LOG2_BYTES_PER_CELL - 1);
610: pfvPutc ( i, (9 - x >> 4 & 7 | 48) + x, PFV_ADDRESS_PALET);
611: } else if (x < 0x100) {
612: int i = PFV_PANEL_WIDTH * y + PFV_MAP_X0 - 3 + (x >>> PFV_LOG2_BYTES_PER_CELL - 1);
613: int t = x >>> 4 & 15;
614: pfvPutc ( i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
615: t = x & 15;
616: pfvPutc (4 * 1 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
617: } else if (x < 0x1000) {
618: int i = PFV_PANEL_WIDTH * y + PFV_MAP_X0 - 5 + (x >>> PFV_LOG2_BYTES_PER_CELL - 1);
619: int t = x >>> 8 & 15;
620: pfvPutc ( i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
621: t = x >>> 4 & 15;
622: pfvPutc (4 * 1 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
623: t = x & 15;
624: pfvPutc (4 * 2 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
625: } else {
626: int i = PFV_PANEL_WIDTH * y + PFV_MAP_X0 - 7 + (x >>> PFV_LOG2_BYTES_PER_CELL - 1);
627: int t = x >>> 12 & 15;
628: pfvPutc ( i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
629: t = x >>> 8 & 15;
630: pfvPutc (4 * 1 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
631: t = x >>> 4 & 15;
632: pfvPutc (4 * 2 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
633: t = x & 15;
634: pfvPutc (4 * 3 + i, (9 - t >> 4 & 7 | 48) + t, PFV_ADDRESS_PALET);
635: }
636: }
637: }
638:
639: long newestRecord = BranchLog.blgNewestRecord;
640: long oldestRecord = Math.max (0L, BranchLog.blgNewestRecord - 65535L);
641: oldestRecord = newestRecord - (long) Math.min ((256 << pfvSpan) - 1, (int) (newestRecord - oldestRecord));
642: for (long record = oldestRecord; record <= newestRecord; record++) {
643: int palet = 255 - ((int) (newestRecord - record) >>> pfvSpan);
644: int address0, supervisor, address1;
645: {
646: int i = (char) record << BranchLog.BLG_RECORD_SHIFT;
647: address0 = BranchLog.blgArray[i] & ~1;
648: supervisor = BranchLog.blgArray[i] & 1;
649: address1 = BranchLog.blgArray[i + 1];
650: }
651:
652: {
653: int y0 = (int) ((long) pfvMapHeight * (address0 & 0xffffffffL) >>> 32);
654: int y1 = (int) ((long) pfvMapHeight * (address1 & 0xffffffffL) >>> 32);
655: int i = PFV_PANEL_WIDTH * PFV_MAP_Y0 + PFV_BAR_X0 + PFV_PANEL_WIDTH * y0;
656: for (int y = y0; y <= y1; y++) {
657: pfvBitmap[i] =
658: pfvBitmap[i + 1] =
659: pfvBitmap[i + 2] =
660: pfvBitmap[i + 3] =
661: pfvBitmap[i + 4] =
662: pfvBitmap[i + 5] =
663: pfvBitmap[i + 6] =
664: pfvBitmap[i + 7] = (byte) palet;
665: i += PFV_PANEL_WIDTH;
666: }
667: }
668:
669: if ((address0 & 0xffffffffL) <= (pfvAddress1 & 0xffffffffL) && (pfvAddress0 & 0xffffffffL) <= (address1 & 0xffffffffL)) {
670: if ((address0 & 0xffffffffL) < (pfvAddress0 & 0xffffffffL)) {
671: address0 = pfvAddress0;
672: }
673: if ((address1 & 0xffffffffL) > (pfvAddress1 & 0xffffffffL)) {
674: address1 = pfvAddress1;
675: }
676: int line = address0 >>> PFV_LOG2_BYTES_PER_LINE;
677: int line1 = address1 >>> PFV_LOG2_BYTES_PER_LINE;
678: int i0 = PFV_PANEL_WIDTH * PFV_MAP_Y0 + PFV_MAP_X0 + PFV_PANEL_WIDTH * (line - pfvLine0 << 1);
679: int i = i0 + ((address0 & PFV_BYTES_PER_LINE - 2) >>> PFV_LOG2_BYTES_PER_CELL - 1 & -2);
680: for (; line <= line1; line++) {
681: int i1 = i0 + (line < line1 ? PFV_BYTES_PER_LINE - 2 >>> PFV_LOG2_BYTES_PER_CELL - 1 & -2 :
682: (address1 & PFV_BYTES_PER_LINE - 2) >>> PFV_LOG2_BYTES_PER_CELL - 1 & -2);
683: for (; i <= i1; i += 2) {
684: pfvBitmap[i] =
685: pfvBitmap[i + 1] =
686: pfvBitmap[i + PFV_PANEL_WIDTH] =
687: pfvBitmap[i + (PFV_PANEL_WIDTH + 1)] = (byte) palet;
688: }
689: i = i0 += PFV_PANEL_WIDTH << 1;
690: }
691: }
692: }
693: pfvPanel.repaint ();
694: pfvTimer = PFV_INTERVAL;
695: BranchLog.blgLock = false;
696: }
697:
698:
699:
700: public static void pfvPutc (int i, int c, int p) {
701: int t = Indicator.IND_ASCII_3X5[c];
702: if (t << 17 < 0) {
703: pfvBitmap[ i] = (byte) p;
704: }
705: if (t << 18 < 0) {
706: pfvBitmap[ 1 + i] = (byte) p;
707: }
708: if (t << 19 < 0) {
709: pfvBitmap[ 2 + i] = (byte) p;
710: }
711: if (t << 20 < 0) {
712: pfvBitmap[PFV_PANEL_WIDTH + i] = (byte) p;
713: }
714: if (t << 21 < 0) {
715: pfvBitmap[PFV_PANEL_WIDTH + 1 + i] = (byte) p;
716: }
717: if (t << 22 < 0) {
718: pfvBitmap[PFV_PANEL_WIDTH + 2 + i] = (byte) p;
719: }
720: if (t << 23 < 0) {
721: pfvBitmap[PFV_PANEL_WIDTH * 2 + i] = (byte) p;
722: }
723: if ((byte) t < 0) {
724: pfvBitmap[PFV_PANEL_WIDTH * 2 + 1 + i] = (byte) p;
725: }
726: if (t << 25 < 0) {
727: pfvBitmap[PFV_PANEL_WIDTH * 2 + 2 + i] = (byte) p;
728: }
729: if (t << 26 < 0) {
730: pfvBitmap[PFV_PANEL_WIDTH * 3 + i] = (byte) p;
731: }
732: if (t << 27 < 0) {
733: pfvBitmap[PFV_PANEL_WIDTH * 3 + 1 + i] = (byte) p;
734: }
735: if (XEiJ.TEST_BIT_3_SHIFT ? t << 28 < 0 : (t & 8) != 0) {
736: pfvBitmap[PFV_PANEL_WIDTH * 3 + 2 + i] = (byte) p;
737: }
738: if (XEiJ.TEST_BIT_2_SHIFT ? t << 29 < 0 : (t & 4) != 0) {
739: pfvBitmap[PFV_PANEL_WIDTH * 4 + i] = (byte) p;
740: }
741: if (XEiJ.TEST_BIT_1_SHIFT ? t << 30 < 0 : (t & 2) != 0) {
742: pfvBitmap[PFV_PANEL_WIDTH * 4 + 1 + i] = (byte) p;
743: }
744: if (XEiJ.TEST_BIT_0_SHIFT ? t << 31 != 0 : (t & 1) != 0) {
745: pfvBitmap[PFV_PANEL_WIDTH * 4 + 2 + i] = (byte) p;
746: }
747: }
748:
749: }
750:
751:
752: