DebugConsole.java
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13: package xeij;
14:
15: import java.awt.*;
16: import java.awt.datatransfer.*;
17: import java.awt.event.*;
18: import java.lang.*;
19: import java.util.*;
20: import javax.swing.*;
21: import javax.swing.event.*;
22:
23: public class DebugConsole {
24:
25: public static final int DGT_MAX_OUTPUT_LENGTH = 1024 * 64;
26: public static final int DGT_CUT_OUTPUT_LENGTH = DGT_MAX_OUTPUT_LENGTH + 1024 * 4;
27:
28:
29: public static final int DGT_INPUT_MODE_COMMAND = 1;
30: public static final int DGT_INPUT_MODE_PAGE = 2;
31: public static final int DGT_INPUT_MODE_ASSEMBLER = 3;
32: public static int dgtInputMode;
33: public static LinkedList<String> dgtPageList;
34:
35:
36: public static final String DGT_COMMAND_PROMPT = "> ";
37: public static final String DGT_PAGE_PROMPT = "-- more -- [y/n] ";
38: public static String dgtCurrentPrompt;
39:
40:
41: public static JFrame dgtFrame;
42: public static ScrollTextArea dgtBoard;
43: public static JPopupMenu dgtPopupMenu;
44: public static JMenuItem dgtPopupCutMenuItem;
45: public static JMenuItem dgtPopupCopyMenuItem;
46: public static JMenuItem dgtPopupPasteMenuItem;
47: public static JMenuItem dgtPopupSelectAllMenuItem;
48: public static int dgtOutputEnd;
49:
50: public static boolean dgtRequestRegs;
51:
52:
53: public static int dgtAssemblePC;
54: public static int dgtAssembleFC;
55:
56:
57: public static int dgtDisassembleLastTail;
58: public static int dgtDisassemblePC;
59: public static int dgtDisassembleFC;
60:
61:
62: public static int dgtDumpAddress;
63: public static int dgtDumpFunctionCode;
64:
65:
66:
67: public static void dgtInit () {
68: dgtInputMode = DGT_INPUT_MODE_COMMAND;
69: dgtPageList = null;
70: dgtCurrentPrompt = DGT_COMMAND_PROMPT;
71: dgtFrame = null;
72: dgtBoard = null;
73: dgtPopupMenu = null;
74: dgtPopupCutMenuItem = null;
75: dgtPopupCopyMenuItem = null;
76: dgtPopupPasteMenuItem = null;
77: dgtPopupSelectAllMenuItem = null;
78: dgtOutputEnd = dgtCurrentPrompt.length ();
79: dgtRequestRegs = false;
80: dgtAssemblePC = 0;
81: dgtAssembleFC = 6;
82: dgtDisassembleLastTail = 0;
83: dgtDisassemblePC = 0;
84: dgtDisassembleFC = 6;
85: dgtDumpAddress = 0;
86: dgtDumpFunctionCode = 5;
87: }
88:
89:
90:
91:
92: public static void dgtMake () {
93:
94:
95: String initialText = (Multilingual.mlnJapanese ?
96: "[ h で使用法を表示]\n" :
97: "[enter h to display usage]\n") + dgtCurrentPrompt;
98: dgtOutputEnd = initialText.length ();
99: dgtBoard = ComponentFactory.createScrollTextArea (initialText, 500, 600, true);
100: dgtBoard.setUnderlineCursorOn (true);
101: dgtBoard.setLineWrap (true);
102: dgtBoard.addDocumentListener (new DocumentListener () {
103: @Override public void changedUpdate (DocumentEvent de) {
104: }
105: @Override public void insertUpdate (DocumentEvent de) {
106: if (de.getOffset () < dgtOutputEnd) {
107: dgtOutputEnd += de.getLength ();
108: }
109: }
110: @Override public void removeUpdate (DocumentEvent de) {
111: if (de.getOffset () < dgtOutputEnd) {
112: dgtOutputEnd -= Math.min (de.getLength (), dgtOutputEnd - de.getOffset ());
113: }
114: }
115: });
116: dgtBoard.addKeyListener (new KeyAdapter () {
117: @Override public void keyPressed (KeyEvent ke) {
118: int code = ke.getKeyCode ();
119: int modifiersEx = ke.getModifiersEx ();
120: if (code == KeyEvent.VK_ENTER &&
121: (modifiersEx & (InputEvent.ALT_DOWN_MASK |
122: InputEvent.CTRL_DOWN_MASK |
123: InputEvent.META_DOWN_MASK)) == 0) {
124: if ((modifiersEx & InputEvent.SHIFT_DOWN_MASK) == 0) {
125: ke.consume ();
126:
127: dgtEnter ();
128: } else {
129: ke.consume ();
130:
131: dgtBoard.replaceRange ("\n", dgtBoard.getSelectionStart (), dgtBoard.getSelectionEnd ());
132: }
133: }
134: }
135: });
136:
137:
138: ActionListener popupActionListener = new ActionListener () {
139: @Override public void actionPerformed (ActionEvent ae) {
140: switch (ae.getActionCommand ()) {
141: case "Cut":
142: dgtCut ();
143: break;
144: case "Copy":
145: dgtCopy ();
146: break;
147: case "Paste":
148: dgtPaste ();
149: break;
150: case "Select All":
151: dgtSelectAll ();
152: break;
153: }
154: }
155: };
156: dgtPopupMenu = ComponentFactory.createPopupMenu (
157: dgtPopupCutMenuItem = Multilingual.mlnText (ComponentFactory.createMenuItem ("Cut", 'T', popupActionListener), "ja", "切り取り"),
158: dgtPopupCopyMenuItem = Multilingual.mlnText (ComponentFactory.createMenuItem ("Copy", 'C', popupActionListener), "ja", "コピー"),
159: dgtPopupPasteMenuItem = Multilingual.mlnText (ComponentFactory.createMenuItem ("Paste", 'P', popupActionListener), "ja", "貼り付け"),
160: ComponentFactory.createHorizontalSeparator (),
161: dgtPopupSelectAllMenuItem = Multilingual.mlnText (ComponentFactory.createMenuItem ("Select All", 'A', popupActionListener), "ja", "すべて選択")
162: );
163: dgtBoard.addMouseListener (new MouseAdapter () {
164: @Override public void mousePressed (MouseEvent me) {
165: dgtShowPopup (me);
166: }
167: @Override public void mouseReleased (MouseEvent me) {
168: dgtShowPopup (me);
169: }
170: });
171:
172:
173: dgtFrame = Multilingual.mlnTitle (
174: ComponentFactory.createRestorableSubFrame (
175: Settings.SGS_DGT_FRAME_KEY,
176: "Console",
177: null,
178: dgtBoard
179: ),
180: "ja", "コンソール");
181:
182: dgtBoard.setCaretPosition (dgtOutputEnd);
183:
184: }
185:
186:
187:
188:
189: public static void dgtShowPopup (MouseEvent me) {
190: if (me.isPopupTrigger ()) {
191:
192: boolean enableCutAndCopy = XEiJ.clpClipboard != null && dgtBoard.getSelectionStart () != dgtBoard.getSelectionEnd ();
193: ComponentFactory.setEnabled (dgtPopupCutMenuItem, enableCutAndCopy);
194: ComponentFactory.setEnabled (dgtPopupCopyMenuItem, enableCutAndCopy);
195:
196: ComponentFactory.setEnabled (dgtPopupPasteMenuItem, XEiJ.clpClipboard != null && XEiJ.clpClipboard.isDataFlavorAvailable (DataFlavor.stringFlavor));
197:
198: ComponentFactory.setEnabled (dgtPopupSelectAllMenuItem, XEiJ.clpClipboard != null);
199:
200: dgtPopupMenu.show (me.getComponent (), me.getX (), me.getY ());
201: }
202: }
203:
204:
205:
206: public static void dgtCut () {
207: if (XEiJ.clpClipboard != null) {
208:
209: XEiJ.clpClipboardString = dgtBoard.getSelectedText ();
210: try {
211: XEiJ.clpClipboard.setContents (XEiJ.clpStringContents, XEiJ.clpClipboardOwner);
212: XEiJ.clpIsClipboardOwner = true;
213: } catch (Exception e) {
214: return;
215: }
216:
217: dgtBoard.replaceRange ("", dgtBoard.getSelectionStart (), dgtBoard.getSelectionEnd ());
218: }
219: }
220:
221:
222:
223: public static void dgtCopy () {
224: if (XEiJ.clpClipboard != null) {
225:
226: String selectedText = dgtBoard.getSelectedText ();
227: if (selectedText != null) {
228: XEiJ.clpClipboardString = selectedText;
229: try {
230: XEiJ.clpClipboard.setContents (XEiJ.clpStringContents, XEiJ.clpClipboardOwner);
231: XEiJ.clpIsClipboardOwner = true;
232: } catch (Exception e) {
233: return;
234: }
235: }
236: }
237: }
238:
239:
240:
241: public static void dgtPaste () {
242: if (XEiJ.clpClipboard != null) {
243:
244: String string = null;
245: try {
246: string = (String) XEiJ.clpClipboard.getData (DataFlavor.stringFlavor);
247: } catch (Exception e) {
248: return;
249: }
250:
251: dgtBoard.replaceRange (string, dgtBoard.getSelectionStart (), dgtBoard.getSelectionEnd ());
252: }
253: }
254:
255:
256:
257: public static void dgtSelectAll () {
258: if (XEiJ.clpClipboard != null) {
259:
260: dgtBoard.selectAll ();
261: }
262: }
263:
264:
265: public static void dgtStart () {
266: if (RestorableFrame.rfmGetOpened (Settings.SGS_DGT_FRAME_KEY)) {
267: dgtOpen ();
268: }
269: }
270:
271:
272:
273: public static void dgtOpen () {
274: if (dgtFrame == null) {
275: dgtMake ();
276: }
277: XEiJ.pnlExitFullScreen (false);
278: dgtFrame.setVisible (true);
279: }
280:
281:
282:
283: public static void dgtPrintChar (int c) {
284: if (c == 0x08) {
285: if (0 < dgtOutputEnd) {
286: if (dgtBoard != null) {
287: dgtBoard.replaceRange ("", dgtOutputEnd - 1, dgtOutputEnd);
288: dgtOutputEnd--;
289: dgtBoard.setCaretPosition (dgtOutputEnd);
290: }
291: }
292: } else if (0x20 <= c && c != 0x7f || c == 0x09 || c == 0x0a) {
293: if (dgtBoard != null) {
294: dgtBoard.insert (String.valueOf ((char) c), dgtOutputEnd);
295: dgtOutputEnd++;
296: if (DGT_CUT_OUTPUT_LENGTH <= dgtOutputEnd) {
297: dgtBoard.replaceRange ("", 0, dgtOutputEnd - DGT_MAX_OUTPUT_LENGTH);
298: dgtOutputEnd = DGT_MAX_OUTPUT_LENGTH;
299: }
300: dgtBoard.setCaretPosition (dgtOutputEnd);
301: }
302: }
303: }
304:
305:
306:
307:
308: public static void dgtPrint (String s) {
309: if (s == null) {
310: return;
311: }
312: if (dgtFrame != null) {
313: dgtBoard.insert (s, dgtOutputEnd);
314: dgtOutputEnd += s.length ();
315: if (DGT_CUT_OUTPUT_LENGTH <= dgtOutputEnd) {
316: dgtBoard.replaceRange ("", 0, dgtOutputEnd - DGT_MAX_OUTPUT_LENGTH);
317: dgtOutputEnd = DGT_MAX_OUTPUT_LENGTH;
318: }
319: dgtBoard.setCaretPosition (dgtOutputEnd);
320: }
321: }
322:
323:
324:
325:
326: public static void dgtPrintln (String s) {
327: dgtPrint (s);
328: dgtPrintChar ('\n');
329: }
330:
331:
332:
333: public static void dgtEnter () {
334: String text = dgtBoard.getText ();
335: int length = text.length ();
336: int outputLineStart = text.lastIndexOf ('\n', dgtOutputEnd - 1) + 1;
337: int caretLineStart = text.lastIndexOf ('\n', dgtBoard.getCaretPosition () - 1) + 1;
338: if (outputLineStart <= caretLineStart) {
339: dgtBoard.replaceRange ("", dgtOutputEnd, length);
340: dgtSend (text.substring (dgtOutputEnd, length));
341: } else if (outputLineStart < dgtOutputEnd) {
342: String prompt = text.substring (outputLineStart, dgtOutputEnd);
343: int caretLineEnd = text.indexOf ('\n', caretLineStart);
344: if (caretLineEnd == -1) {
345: caretLineEnd = length;
346: }
347: String line = text.substring (caretLineStart, caretLineEnd);
348: int start = line.indexOf (prompt);
349: if (0 <= start) {
350: dgtOutputEnd = length;
351: if (text.charAt (dgtOutputEnd - 1) != '\n' && !text.endsWith ("\n" + prompt)) {
352: dgtBoard.insert ("\n", dgtOutputEnd);
353: dgtOutputEnd++;
354: if (DGT_CUT_OUTPUT_LENGTH <= dgtOutputEnd) {
355: dgtBoard.replaceRange ("", 0, dgtOutputEnd - DGT_MAX_OUTPUT_LENGTH);
356: dgtOutputEnd = DGT_MAX_OUTPUT_LENGTH;
357: }
358: }
359: dgtBoard.setCaretPosition (dgtOutputEnd);
360: dgtSend (line.substring (start + prompt.length ()));
361: }
362: }
363: }
364:
365:
366:
367: public static void dgtSend (String s) {
368: dgtPrintln (s);
369: if (dgtInputMode == DGT_INPUT_MODE_COMMAND) {
370: ExpressionEvaluator.ExpressionElement nodeTree = XEiJ.fpuBox.evxParse (s, ExpressionEvaluator.EVM_COMMAND);
371: if (nodeTree != null) {
372: nodeTree.exlEval (ExpressionEvaluator.EVM_COMMAND);
373: if (nodeTree.exlValueType == ExpressionEvaluator.ElementType.ETY_FLOAT) {
374: dgtPrintln (nodeTree.exlFloatValue.toString ());
375: } else if (nodeTree.exlValueType == ExpressionEvaluator.ElementType.ETY_STRING) {
376: dgtPrintln (nodeTree.exlStringValue);
377: }
378: }
379: } else if (dgtInputMode == DGT_INPUT_MODE_PAGE) {
380: if (!(s.equals ("") ||
381: s.toLowerCase ().startsWith (" ") ||
382: s.toLowerCase ().startsWith ("y"))) {
383: dgtPageList = null;
384: }
385: dgtPrintPage ();
386: } else if (dgtInputMode == DGT_INPUT_MODE_ASSEMBLER) {
387: if (s.equals (".")) {
388: dgtInputMode = DGT_INPUT_MODE_COMMAND;
389: dgtCurrentPrompt = DGT_COMMAND_PROMPT;
390: } else {
391: byte[] binary = Assembler.asmAssemble (dgtAssemblePC, s);
392: if (binary != null && 0 < binary.length) {
393: for (int i = 0; i < binary.length; i++) {
394: MC68060.mmuPokeByte (dgtAssemblePC + i, binary[i], dgtAssembleFC);
395: }
396:
397: int itemAddress = dgtAssemblePC;
398: dgtAssemblePC += binary.length;
399: dgtMakeAssemblerPrompt ();
400: int supervisor = DebugConsole.dgtAssembleFC & 4;
401: StringBuilder sb = new StringBuilder ();
402: while (itemAddress < dgtAssemblePC) {
403: String code = Disassembler.disDisassemble (new StringBuilder (), itemAddress, supervisor).toString ();
404: int itemEndAddress = Disassembler.disPC;
405: if (dgtAssemblePC < itemEndAddress) {
406: itemEndAddress = dgtAssemblePC;
407: StringBuilder sb2 = new StringBuilder ();
408: sb2.append ("dc.w ");
409: for (int a = itemAddress; a < itemEndAddress; a += 2) {
410: if (itemAddress < a) {
411: sb2.append (',');
412: }
413: XEiJ.fmtHex4 (sb2.append ('$'), MC68060.mmuPeekWordZeroCode (a, supervisor));
414: }
415: code = sb2.toString ();
416: }
417:
418: int lineAddress = itemAddress;
419: int lineEndAddress = Math.min (lineAddress + 10, itemEndAddress);
420:
421: XEiJ.fmtHex8 (sb, lineAddress).append (" ");
422:
423: for (int a = lineAddress; a < lineEndAddress; a += 2) {
424: XEiJ.fmtHex4 (sb, MC68060.mmuPeekWordZeroCode (a, supervisor));
425: }
426: sb.append (XEiJ.DBG_SPACES, 0, 2 * Math.max (0, lineAddress + 10 - lineEndAddress) + 2);
427:
428: sb.append (code).append ('\n');
429:
430: while (lineEndAddress < itemEndAddress) {
431: lineAddress = lineEndAddress;
432: lineEndAddress = Math.min (lineAddress + 10, itemEndAddress);
433:
434: XEiJ.fmtHex8 (sb, lineAddress).append (" ");
435:
436: for (int a = lineAddress; a < lineEndAddress; a += 2) {
437: XEiJ.fmtHex4 (sb, MC68060.mmuPeekWordZeroCode (a, supervisor));
438: }
439: sb.append ('\n');
440: }
441: itemAddress = itemEndAddress;
442: }
443: dgtPrint (sb.toString ());
444: }
445: }
446: }
447: if (!dgtRequestRegs) {
448: dgtPrintPrompt ();
449: }
450: }
451:
452:
453:
454: public static void dgtMakeAssemblerPrompt () {
455: StringBuilder sb = XEiJ.fmtHex8 (new StringBuilder (), dgtAssemblePC);
456: if (Model.MPU_MC68LC040 <= XEiJ.currentMPU) {
457: sb.append ('@').append (dgtAssembleFC);
458: }
459: dgtCurrentPrompt = sb.append (" ").toString ();
460: }
461:
462:
463:
464:
465: public static void dgtPrintPrompt () {
466: String text = dgtBoard.getText ();
467: if (!text.substring (text.lastIndexOf ('\n', dgtOutputEnd - 1) + 1, dgtOutputEnd).equals (dgtCurrentPrompt)) {
468: dgtPrint (text.endsWith ("\n") ? dgtCurrentPrompt : "\n" + dgtCurrentPrompt);
469: }
470: }
471:
472:
473:
474: public static void dgtPrintPage () {
475: if (dgtPageList != null && !dgtPageList.isEmpty ()) {
476: dgtPrint (dgtPageList.pollFirst ());
477: if (!dgtPageList.isEmpty ()) {
478:
479: DebugConsole.dgtInputMode = DebugConsole.DGT_INPUT_MODE_PAGE;
480: dgtCurrentPrompt = DGT_PAGE_PROMPT;
481: }
482: }
483: if (dgtPageList == null || dgtPageList.isEmpty ()) {
484: dgtPageList = null;
485:
486: dgtInputMode = DGT_INPUT_MODE_COMMAND;
487: dgtCurrentPrompt = DGT_COMMAND_PROMPT;
488: }
489: dgtPrintPrompt ();
490: }
491:
492: }
493:
494:
495: