DataBreakPoint.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:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99: package xeij;
100:
101: import java.awt.*;
102: import java.awt.event.*;
103: import java.lang.*;
104: import java.util.*;
105: import javax.swing.*;
106: import javax.swing.event.*;
107:
108: public class DataBreakPoint {
109:
110: public static final boolean DBP_ON = true;
111:
112:
113: public static final int DBP_BYTE = 0;
114: public static final int DBP_WORD = 1;
115: public static final int DBP_LONG = 2;
116: public static final java.util.List<String> DBP_SIZE_LIST_EN = Arrays.asList ("Byte", "Word", "Long");
117: public static final java.util.List<String> DBP_SIZE_LIST_JA = Arrays.asList ("バイト", "ワード", "ロング");
118:
119:
120: public static final MemoryMappedDevice[] dbpUserMap = DBP_ON ? new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT] : null;
121: public static final MemoryMappedDevice[] dbpSuperMap = DBP_ON ? new MemoryMappedDevice[XEiJ.BUS_PAGE_COUNT] : null;
122: public static MemoryMappedDevice[] dbpMemoryMap;
123:
124:
125: public static ArrayList<DataBreakRecord> dbpList;
126:
127:
128: public static int dbpLock;
129: public static JFrame dbpFrame;
130: public static GridLayout dbpListGridLayout;
131: public static JPanel dbpListPanel;
132:
133:
134:
135: public static void dbpInit () {
136:
137: Arrays.fill (dbpUserMap, MemoryMappedDevice.MMD_NUL);
138: Arrays.fill (dbpSuperMap, MemoryMappedDevice.MMD_NUL);
139: dbpMemoryMap = dbpSuperMap;
140:
141:
142: dbpList = new ArrayList<DataBreakRecord> ();
143:
144: }
145:
146:
147: public static void dbpStart () {
148: if (RestorableFrame.rfmGetOpened (Settings.SGS_DBP_FRAME_KEY)) {
149: dbpOpen ();
150: }
151: }
152:
153:
154:
155: public static void dbpOpen () {
156: if (dbpFrame == null) {
157: dbpMakeFrame ();
158: }
159: XEiJ.dbgVisibleMask |= XEiJ.DBG_DBP_VISIBLE_MASK;
160: XEiJ.pnlExitFullScreen (false);
161: dbpFrame.setVisible (true);
162: }
163:
164:
165:
166:
167: public static void dbpMakeFrame () {
168: dbpLock = 0;
169:
170: ActionListener listener = new ActionListener () {
171: @Override public void actionPerformed (ActionEvent ae) {
172: Object source = ae.getSource ();
173: switch (ae.getActionCommand ()) {
174: case "Add":
175: new DataBreakRecord (0x00000000, DBP_BYTE, 0xff, 0, 0xff, false, 0, 0);
176: break;
177: }
178: }
179: };
180:
181: dbpListGridLayout = new GridLayout (1, 9);
182: dbpListPanel = ComponentFactory.addComponents (
183: new JPanel (dbpListGridLayout),
184: Multilingual.mlnText (ComponentFactory.createLabel ("Enabled"), "ja", "有効"),
185: Multilingual.mlnText (ComponentFactory.createLabel ("Address"), "ja", "アドレス"),
186: Multilingual.mlnText (ComponentFactory.createLabel ("Size"), "ja", "サイズ"),
187: Multilingual.mlnText (ComponentFactory.createLabel ("Mask"), "ja", "マスク"),
188: Multilingual.mlnText (ComponentFactory.createLabel ("Lower"), "ja", "下限"),
189: Multilingual.mlnText (ComponentFactory.createLabel ("Upper"), "ja", "上限"),
190: Multilingual.mlnText (ComponentFactory.createLabel ("Count"), "ja", "回数"),
191: Multilingual.mlnText (ComponentFactory.createLabel ("Threshold"), "ja", "閾値"),
192: Multilingual.mlnText (ComponentFactory.createLabel ("Remove"), "ja", "削除")
193: );
194: dbpFrame = Multilingual.mlnTitle (
195: ComponentFactory.createRestorableSubFrame (
196: Settings.SGS_DBP_FRAME_KEY,
197: "Data break point",
198: null,
199: ComponentFactory.setPreferredSize (
200: ComponentFactory.createBorderPanel (
201:
202: ComponentFactory.createScrollPane (dbpListPanel),
203:
204: null,
205:
206: null,
207:
208: ComponentFactory.createFlowPanel (
209: FlowLayout.CENTER,
210: Multilingual.mlnText (ComponentFactory.createButton ("Add", listener), "ja", "追加")
211: )
212:
213: ),
214: 750, 100)
215: ),
216: "ja", "データブレークポイント");
217:
218: ComponentFactory.addListener (
219: dbpFrame,
220: new WindowAdapter () {
221: @Override public void windowClosing (WindowEvent we) {
222: XEiJ.dbgVisibleMask &= ~XEiJ.DBG_DBP_VISIBLE_MASK;
223: }
224: });
225: }
226:
227:
228:
229:
230:
231:
232: public static void dbpBreak (int size, int address, int data) {
233: if (size == DBP_BYTE) {
234: for (DataBreakRecord r : dbpList) {
235: if (r.dbrEnabled) {
236: if (r.dbrSize == DBP_BYTE) {
237: if (address == r.dbrAddress) {
238: int masked = data & r.dbrMask;
239: if (r.dbrLower <= r.dbrUpper ?
240: r.dbrLower <= masked && masked <= r.dbrUpper :
241: masked <= r.dbrUpper || r.dbrLower <= masked) {
242: r.dbrSetCount (r.dbrCount + 1);
243: if (r.dbrThreshold <= r.dbrCount) {
244: XEiJ.mpuStop (null);
245: }
246: }
247: }
248: }
249: }
250: }
251: } else if (size == DBP_WORD) {
252: for (DataBreakRecord r : dbpList) {
253: if (r.dbrEnabled) {
254: if (r.dbrSize == DBP_BYTE) {
255: if (address == r.dbrAddress) {
256: int masked = data >>> 8 & r.dbrMask;
257: if (r.dbrLower <= r.dbrUpper ?
258: r.dbrLower <= masked && masked <= r.dbrUpper :
259: masked <= r.dbrUpper || r.dbrLower <= masked) {
260: r.dbrSetCount (r.dbrCount + 1);
261: if (r.dbrThreshold <= r.dbrCount) {
262: XEiJ.mpuStop (null);
263: }
264: }
265: } else if (address + 1 == r.dbrAddress) {
266: int masked = data & r.dbrMask;
267: if (r.dbrLower <= r.dbrUpper ?
268: r.dbrLower <= masked && masked <= r.dbrUpper :
269: masked <= r.dbrUpper || r.dbrLower <= masked) {
270: r.dbrSetCount (r.dbrCount + 1);
271: if (r.dbrThreshold <= r.dbrCount) {
272: XEiJ.mpuStop (null);
273: }
274: }
275: }
276: } else if (r.dbrSize == DBP_WORD) {
277: if (address == r.dbrAddress) {
278: int masked = data & r.dbrMask;
279: if (r.dbrLower <= r.dbrUpper ?
280: r.dbrLower <= masked && masked <= r.dbrUpper :
281: masked <= r.dbrUpper || r.dbrLower <= masked) {
282: r.dbrSetCount (r.dbrCount + 1);
283: if (r.dbrThreshold <= r.dbrCount) {
284: XEiJ.mpuStop (null);
285: }
286: }
287: }
288: }
289: }
290: }
291: } else if (size == DBP_LONG) {
292: for (DataBreakRecord r : dbpList) {
293: if (r.dbrEnabled) {
294: if (r.dbrSize == DBP_BYTE) {
295: if (address == r.dbrAddress) {
296: int masked = data >>> 24 & r.dbrMask;
297: if (r.dbrLower <= r.dbrUpper ?
298: r.dbrLower <= masked && masked <= r.dbrUpper :
299: masked <= r.dbrUpper || r.dbrLower <= masked) {
300: r.dbrSetCount (r.dbrCount + 1);
301: if (r.dbrThreshold <= r.dbrCount) {
302: XEiJ.mpuStop (null);
303: }
304: }
305: } else if (address + 1 == r.dbrAddress) {
306: int masked = data >>> 16 & r.dbrMask;
307: if (r.dbrLower <= r.dbrUpper ?
308: r.dbrLower <= masked && masked <= r.dbrUpper :
309: masked <= r.dbrUpper || r.dbrLower <= masked) {
310: r.dbrSetCount (r.dbrCount + 1);
311: if (r.dbrThreshold <= r.dbrCount) {
312: XEiJ.mpuStop (null);
313: }
314: }
315: } else if (address + 2 == r.dbrAddress) {
316: int masked = data >>> 8 & r.dbrMask;
317: if (r.dbrLower <= r.dbrUpper ?
318: r.dbrLower <= masked && masked <= r.dbrUpper :
319: masked <= r.dbrUpper || r.dbrLower <= masked) {
320: r.dbrSetCount (r.dbrCount + 1);
321: if (r.dbrThreshold <= r.dbrCount) {
322: XEiJ.mpuStop (null);
323: }
324: }
325: } else if (address + 3 == r.dbrAddress) {
326: int masked = data & r.dbrMask;
327: if (r.dbrLower <= r.dbrUpper ?
328: r.dbrLower <= masked && masked <= r.dbrUpper :
329: masked <= r.dbrUpper || r.dbrLower <= masked) {
330: r.dbrSetCount (r.dbrCount + 1);
331: if (r.dbrThreshold <= r.dbrCount) {
332: XEiJ.mpuStop (null);
333: }
334: }
335: }
336: } else if (r.dbrSize == DBP_WORD) {
337: if (address == r.dbrAddress) {
338: int masked = data >> 16 & r.dbrMask;
339: if (r.dbrLower <= r.dbrUpper ?
340: r.dbrLower <= masked && masked <= r.dbrUpper :
341: masked <= r.dbrUpper || r.dbrLower <= masked) {
342: r.dbrSetCount (r.dbrCount + 1);
343: if (r.dbrThreshold <= r.dbrCount) {
344: XEiJ.mpuStop (null);
345: }
346: }
347: } else if (address + 2 == r.dbrAddress) {
348: int masked = data & r.dbrMask;
349: if (r.dbrLower <= r.dbrUpper ?
350: r.dbrLower <= masked && masked <= r.dbrUpper :
351: masked <= r.dbrUpper || r.dbrLower <= masked) {
352: r.dbrSetCount (r.dbrCount + 1);
353: if (r.dbrThreshold <= r.dbrCount) {
354: XEiJ.mpuStop (null);
355: }
356: }
357: }
358: } else if (r.dbrSize == DBP_LONG) {
359: if (address == r.dbrAddress) {
360: int masked = data & r.dbrMask;
361: if (Integer.compareUnsigned (r.dbrLower, r.dbrUpper) <= 0 ?
362: Integer.compareUnsigned (r.dbrLower, masked) <= 0 && Integer.compareUnsigned (masked, r.dbrUpper) <= 0 :
363: Integer.compareUnsigned (masked, r.dbrUpper) <= 0 || Integer.compareUnsigned (r.dbrLower, masked) <= 0) {
364: r.dbrSetCount (r.dbrCount + 1);
365: if (r.dbrThreshold <= r.dbrCount) {
366: XEiJ.mpuStop (null);
367: }
368: }
369: }
370: }
371: }
372: }
373: }
374: }
375:
376:
377:
378: public static class DataBreakRecord implements Comparable<DataBreakRecord> {
379:
380:
381: public int dbrAddress;
382: public int dbrSize;
383: public int dbrMask;
384: public int dbrLower;
385: public int dbrUpper;
386:
387:
388: public boolean dbrEnabled;
389: public int dbrCount;
390: public int dbrThreshold;
391:
392:
393: public Box dbrEnabledBox;
394: public JCheckBox dbrEnabledCheckBox;
395: public Hex8Spinner dbrAddressSpinner;
396: public JSpinner dbrSizeSpinner;
397: public JLabel[] dbrSizeLabels;
398: public Hex8Spinner dbrMaskSpinner;
399: public Hex8Spinner dbrLowerSpinner;
400: public Hex8Spinner dbrUpperSpinner;
401: public JSpinner dbrCountSpinner;
402: public SpinnerNumberModel dbrCountModel;
403: public JSpinner dbrThresholdSpinner;
404: public SpinnerNumberModel dbrThresholdModel;
405: public Box dbrRemoveBox;
406: public JButton dbrRemoveButton;
407:
408:
409: @Override public int compareTo (DataBreakRecord r) {
410: int t = Integer.compareUnsigned (dbrAddress, r.dbrAddress);
411: if (t == 0) {
412: t = Integer.compareUnsigned (dbrSize, r.dbrSize);
413: if (t == 0) {
414: t = Integer.compareUnsigned (dbrMask, r.dbrMask);
415: if (t == 0) {
416: t = Integer.compareUnsigned (dbrLower, r.dbrLower);
417: if (t == 0) {
418: t = Integer.compareUnsigned (dbrUpper, r.dbrUpper);
419: }
420: }
421: }
422: }
423: return t;
424: }
425:
426:
427:
428: @SuppressWarnings ("this-escape") public DataBreakRecord (int address, int size, int mask, int lower, int upper, boolean enabled, int count, int threshold) {
429:
430:
431: mask &= size == DBP_BYTE ? 0xff : size == DBP_WORD ? 0xffff : 0xffffffff;
432: lower &= mask;
433: upper &= mask;
434:
435:
436: dbrAddress = address;
437: dbrSize = size;
438: dbrMask = mask;
439: dbrLower = lower;
440: dbrUpper = upper;
441:
442:
443: dbrEnabled = enabled;
444: dbrCount = count;
445: dbrThreshold = threshold;
446:
447:
448: ActionListener listener = new ActionListener () {
449: @Override public void actionPerformed (ActionEvent ae) {
450: Object source = ae.getSource ();
451: switch (ae.getActionCommand ()) {
452: case "Enabled":
453: dbrSetEnabled (((JCheckBox) source).isSelected ());
454: break;
455: case "Remove":
456: dbrRemove ();
457: break;
458: }
459: }
460: };
461:
462:
463: dbrEnabledBox = ComponentFactory.createGlueBox (
464: dbrEnabledCheckBox = Multilingual.mlnText (ComponentFactory.createCheckBox (dbrEnabled, "Enabled", listener), "ja", "有効")
465: );
466:
467:
468: dbrAddressSpinner = ComponentFactory.createHex8Spinner (dbrAddress, 0xffffffff, false, new ChangeListener () {
469: @Override public void stateChanged (ChangeEvent ce) {
470: if (dbpLock == 0) {
471: dbrSetAddress (((Hex8Spinner) ce.getSource ()).getIntValue ());
472: }
473: }
474: });
475:
476:
477: dbrSizeSpinner = Multilingual.mlnList (
478: ComponentFactory.createListSpinner (
479: DBP_SIZE_LIST_EN,
480: DBP_SIZE_LIST_EN.get (dbrSize),
481: new ChangeListener () {
482: @Override public void stateChanged (ChangeEvent ce) {
483: if (dbpLock == 0) {
484: SpinnerListModel model = (SpinnerListModel) ((JSpinner) ce.getSource ()).getModel ();
485: dbrSetSize (model.getList ().indexOf (model.getValue ()));
486: }
487: }
488: }),
489: "ja", DBP_SIZE_LIST_JA);
490:
491:
492: dbrMaskSpinner = ComponentFactory.createHex8Spinner (dbrMask, -1, false, new ChangeListener () {
493: @Override public void stateChanged (ChangeEvent ce) {
494: if (dbpLock == 0) {
495: dbrSetMask (((Hex8Spinner) ce.getSource ()).getIntValue ());
496: }
497: }
498: });
499:
500:
501: dbrLowerSpinner = ComponentFactory.createHex8Spinner (dbrLower, -1, false, new ChangeListener () {
502: @Override public void stateChanged (ChangeEvent ce) {
503: if (dbpLock == 0) {
504: dbrSetLower (((Hex8Spinner) ce.getSource ()).getIntValue ());
505: }
506: }
507: });
508:
509:
510: dbrUpperSpinner = ComponentFactory.createHex8Spinner (dbrUpper, -1, false, new ChangeListener () {
511: @Override public void stateChanged (ChangeEvent ce) {
512: if (dbpLock == 0) {
513: dbrSetUpper (((Hex8Spinner) ce.getSource ()).getIntValue ());
514: }
515: }
516: });
517:
518:
519: dbrCountSpinner = ComponentFactory.createNumberSpinner (
520: dbrCountModel = new SpinnerNumberModel (dbrCount, 0, 99999999, 1),
521: 8,
522: new ChangeListener () {
523: @Override public void stateChanged (ChangeEvent ce) {
524: if (dbpLock == 0) {
525: dbrSetCount (dbrCountModel.getNumber ().intValue ());
526: }
527: }
528: });
529:
530:
531: dbrThresholdSpinner = ComponentFactory.createNumberSpinner (
532: dbrThresholdModel = new SpinnerNumberModel (dbrThreshold, 0, 99999999, 1),
533: 8,
534: new ChangeListener () {
535: @Override public void stateChanged (ChangeEvent ce) {
536: if (dbpLock == 0) {
537: dbrSetThreshold (dbrThresholdModel.getNumber ().intValue ());
538: }
539: }
540: });
541:
542:
543: dbrRemoveBox = ComponentFactory.createGlueBox (
544: dbrRemoveButton = Multilingual.mlnText (ComponentFactory.createButton ("Remove", listener), "ja", "削除")
545: );
546:
547:
548: dbpList.add (this);
549:
550:
551: dbpListGridLayout.setRows (dbpListGridLayout.getRows () + 1);
552: ComponentFactory.addComponents (
553: dbpListPanel,
554: dbrEnabledBox,
555: dbrAddressSpinner,
556: dbrSizeSpinner,
557: dbrMaskSpinner,
558: dbrLowerSpinner,
559: dbrUpperSpinner,
560: dbrCountSpinner,
561: dbrThresholdSpinner,
562: dbrRemoveBox
563: );
564: dbpListPanel.validate ();
565: dbpListPanel.repaint ();
566:
567:
568: dbrSetEnabled (dbrEnabled);
569:
570: }
571:
572:
573:
574: public void dbrRemove () {
575:
576:
577: dbrSetEnabled (false);
578:
579:
580: ComponentFactory.removeComponents (
581: dbpListPanel,
582: dbrEnabledBox,
583: dbrAddressSpinner,
584: dbrSizeSpinner,
585: dbrMaskSpinner,
586: dbrLowerSpinner,
587: dbrUpperSpinner,
588: dbrCountSpinner,
589: dbrThresholdSpinner,
590: dbrRemoveBox
591: );
592: dbpListGridLayout.setRows (dbpListGridLayout.getRows () - 1);
593: dbpListPanel.validate ();
594: dbpListPanel.repaint ();
595:
596:
597: dbpList.remove (this);
598:
599: }
600:
601:
602:
603: public void dbrSetAddress (int address) {
604: if (dbrAddress != address) {
605: dbrAddress = address;
606: if (dbrAddressSpinner != null) {
607: dbpLock++;
608: dbrAddressSpinner.setIntValue (address);
609: dbpLock--;
610: }
611: }
612: }
613:
614:
615:
616: public void dbrSetSize (int size) {
617: if (dbrSize != size) {
618: dbrSize = size;
619: if (dbrSizeSpinner != null) {
620: dbpLock++;
621: dbrSizeSpinner.setValue (((SpinnerListModel) dbrSizeSpinner.getModel ()).getList ().get (size));
622: dbpLock--;
623: }
624: dbrSetMask (dbrMask & (dbrSize == DBP_BYTE ? 0xff : dbrSize == DBP_WORD ? 0xffff : 0xffffffff));
625: }
626: }
627:
628:
629:
630: public void dbrSetMask (int mask) {
631: mask &= dbrSize == DBP_BYTE ? 0xff : dbrSize == DBP_WORD ? 0xffff : 0xffffffff;
632: if (dbrMask != mask) {
633: dbrMask = mask;
634: if (dbrMaskSpinner != null) {
635: dbpLock++;
636: dbrMaskSpinner.setIntValue (mask);
637: dbpLock--;
638: }
639: dbrSetLower (dbrLower);
640: dbrSetUpper (dbrUpper);
641: }
642: }
643:
644:
645:
646: public void dbrSetLower (int lower) {
647: lower &= dbrMask;
648: if (dbrLower != lower) {
649: dbrLower = lower;
650: if (dbrLowerSpinner != null) {
651: dbpLock++;
652: dbrLowerSpinner.setIntValue (lower);
653: dbpLock--;
654: }
655: }
656: }
657:
658:
659:
660: public void dbrSetUpper (int upper) {
661: upper &= dbrMask;
662: if (dbrUpper != upper) {
663: dbrUpper = upper;
664: if (dbrUpperSpinner != null) {
665: dbpLock++;
666: dbrUpperSpinner.setIntValue (upper);
667: dbpLock--;
668: }
669: }
670: }
671:
672:
673:
674: public void dbrSetEnabled (boolean enabled) {
675: if (dbrEnabled != enabled) {
676: dbrEnabled = enabled;
677: dbrEnabledCheckBox.setSelected (enabled);
678: }
679: int p = dbrAddress >>> XEiJ.BUS_PAGE_BITS;
680: if (dbrEnabled) {
681:
682: dbpUserMap[p] = dbpSuperMap[p] = MemoryMappedDevice.MMD_DBP;
683: } else {
684:
685: boolean exists = false;
686: for (DataBreakRecord r : dbpList) {
687: if (r.dbrAddress >>> XEiJ.BUS_PAGE_BITS == p) {
688: exists = true;
689: break;
690: }
691: }
692: dbpUserMap[p] = exists ? MemoryMappedDevice.MMD_DBP : XEiJ.busUserMap[p];
693: dbpSuperMap[p] = exists ? MemoryMappedDevice.MMD_DBP : XEiJ.busSuperMap[p];
694: }
695: }
696:
697:
698:
699: public void dbrSetCount (int count) {
700: if (dbrCount != count) {
701: dbrCount = count;
702: if (dbrCountSpinner != null) {
703: dbpLock++;
704: dbrCountSpinner.setValue (Integer.valueOf (count));
705: dbpLock--;
706: }
707: }
708: }
709:
710:
711:
712: public void dbrSetThreshold (int threshold) {
713: if (dbrThreshold != threshold) {
714: dbrThreshold = threshold;
715: if (dbrThresholdSpinner != null) {
716: dbpLock++;
717: dbrThresholdSpinner.setValue (Integer.valueOf (threshold));
718: dbpLock--;
719: }
720: }
721: }
722:
723: }
724:
725:
726:
727: }
728:
729:
730: