kopia lustrzana https://github.com/maccasoft/z80-tools
Implemented debugger breakpoints
rodzic
0f6f75c31b
commit
3e9b6dcdc4
|
@ -63,6 +63,8 @@ import org.eclipse.swt.events.DisposeEvent;
|
|||
import org.eclipse.swt.events.DisposeListener;
|
||||
import org.eclipse.swt.events.MenuEvent;
|
||||
import org.eclipse.swt.events.MenuListener;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.SelectionAdapter;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.TraverseEvent;
|
||||
|
@ -237,7 +239,7 @@ public class Application {
|
|||
return;
|
||||
}
|
||||
|
||||
display.asyncExec(stepOverRunnable);
|
||||
display.asyncExec(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -255,7 +257,19 @@ public class Application {
|
|||
return;
|
||||
}
|
||||
|
||||
display.asyncExec(runToLineRunnable);
|
||||
display.asyncExec(this);
|
||||
}
|
||||
};
|
||||
|
||||
final Runnable runCodeRunnable = new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (stepOverPC1 == -1) {
|
||||
return;
|
||||
}
|
||||
proc.execute();
|
||||
display.asyncExec(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -962,6 +976,37 @@ public class Application {
|
|||
menuItem.setMenu(menu);
|
||||
|
||||
MenuItem item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Run\tF5");
|
||||
item.setAccelerator(SWT.F5);
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleRun();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Stop");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleStop();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new MenuItem(menu, SWT.SEPARATOR);
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Step into\tF8");
|
||||
item.setAccelerator(SWT.F8);
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
@ -1008,13 +1053,28 @@ public class Application {
|
|||
new MenuItem(menu, SWT.SEPARATOR);
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Stop");
|
||||
item.setText("Toggle breakpoint\tCtrl+Shift+B");
|
||||
item.setAccelerator(SWT.MOD1 + SWT.MOD2 + 'B');
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleStop();
|
||||
handleToggleBreakpoint();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
item = new MenuItem(menu, SWT.PUSH);
|
||||
item.setText("Clear all breakpoints");
|
||||
item.addListener(SWT.Selection, new Listener() {
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event e) {
|
||||
try {
|
||||
handleClearBreakpoints();
|
||||
} catch (Exception e1) {
|
||||
e1.printStackTrace();
|
||||
}
|
||||
|
@ -1515,6 +1575,13 @@ public class Application {
|
|||
|
||||
viewer = new SourceViewer(composite, new Z80TokenMarker());
|
||||
viewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||
viewer.getStyledText().addMouseListener(new MouseAdapter() {
|
||||
|
||||
@Override
|
||||
public void mouseDoubleClick(MouseEvent e) {
|
||||
handleToggleBreakpoint();
|
||||
}
|
||||
});
|
||||
|
||||
registers = new Registers(composite);
|
||||
registers.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
|
||||
|
@ -2356,36 +2423,43 @@ public class Application {
|
|||
public int breakpoint(int address, int opcode) {
|
||||
|
||||
// Emulate CP/M Syscall at address 5
|
||||
switch (proc.getRegC()) {
|
||||
case 0: // BDOS 0 System Reset
|
||||
out.println("Z80 reset after " + memIoOps.getTstates() + " t-states");
|
||||
break;
|
||||
case 2: // BDOS 2 console char output
|
||||
if (debugTerminal != null) {
|
||||
debugTerminal.write(proc.getRegE());
|
||||
}
|
||||
else {
|
||||
out.write(proc.getRegE());
|
||||
}
|
||||
break;
|
||||
case 9: {// BDOS 9 console string output (string terminated by "$")
|
||||
int strAddr = proc.getRegDE();
|
||||
if (debugTerminal != null) {
|
||||
while (memIoOps.peek8(strAddr) != '$') {
|
||||
debugTerminal.write(memIoOps.peek8(strAddr++));
|
||||
if (address == 0x0005) {
|
||||
switch (proc.getRegC()) {
|
||||
case 0: // BDOS 0 System Reset
|
||||
out.println("Z80 reset after " + memIoOps.getTstates() + " t-states");
|
||||
break;
|
||||
case 2: // BDOS 2 console char output
|
||||
if (debugTerminal != null) {
|
||||
debugTerminal.write(proc.getRegE());
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (memIoOps.peek8(strAddr) != '$') {
|
||||
out.write(memIoOps.peek8(strAddr++));
|
||||
else {
|
||||
out.write(proc.getRegE());
|
||||
}
|
||||
break;
|
||||
case 9: { // BDOS 9 console string output (string terminated by "$")
|
||||
int strAddr = proc.getRegDE();
|
||||
if (debugTerminal != null) {
|
||||
while (memIoOps.peek8(strAddr) != '$') {
|
||||
debugTerminal.write(memIoOps.peek8(strAddr++));
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (memIoOps.peek8(strAddr) != '$') {
|
||||
out.write(memIoOps.peek8(strAddr++));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
out.println("BDOS Call " + proc.getRegC());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
out.println("BDOS Call " + proc.getRegC());
|
||||
break;
|
||||
|
||||
return opcode;
|
||||
}
|
||||
|
||||
handleStop();
|
||||
|
||||
return opcode;
|
||||
}
|
||||
|
||||
|
@ -2584,6 +2658,32 @@ public class Application {
|
|||
updateDebuggerState();
|
||||
}
|
||||
|
||||
private void handleToggleBreakpoint() {
|
||||
int caretOffset = viewer.getStyledText().getCaretOffset();
|
||||
int lineAtOffset = viewer.getStyledText().getLineAtOffset(caretOffset);
|
||||
|
||||
Line line = viewer.getSource().getLines().get(lineAtOffset);
|
||||
if (line != null) {
|
||||
int address = line.getScope().getAddress();
|
||||
viewer.toggleBreakpoint(address);
|
||||
proc.setBreakpoint(address, viewer.isBreakpoint(address));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleClearBreakpoints() {
|
||||
viewer.resetBreakpoints();
|
||||
proc.resetBreakpoints();
|
||||
}
|
||||
|
||||
private void handleRun() {
|
||||
stepOverPC1 = 0;
|
||||
stepOverPC2 = -1;
|
||||
memory.clearUpdates();
|
||||
viewer.getControl().setFocus();
|
||||
|
||||
display.asyncExec(runCodeRunnable);
|
||||
}
|
||||
|
||||
void updateDebuggerState() {
|
||||
memory.update();
|
||||
registers.updateRegisters(proc);
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
|
||||
package com.maccasoft.tools;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.custom.CaretEvent;
|
||||
import org.eclipse.swt.custom.CaretListener;
|
||||
|
@ -37,6 +41,7 @@ public class CodeRuler {
|
|||
|
||||
StyledText text;
|
||||
Source source;
|
||||
boolean[] breakpoint;
|
||||
|
||||
int leftMargin;
|
||||
int rightMargin;
|
||||
|
@ -46,6 +51,9 @@ public class CodeRuler {
|
|||
private int currentLine;
|
||||
private Color currentLineBackground;
|
||||
|
||||
private Font font;
|
||||
private Font fontBold;
|
||||
|
||||
final PaintListener paintListener = new PaintListener() {
|
||||
|
||||
@Override
|
||||
|
@ -101,6 +109,8 @@ public class CodeRuler {
|
|||
|
||||
currentLine = 0;
|
||||
currentLineBackground = new Color(Display.getDefault(), 232, 242, 254);
|
||||
|
||||
breakpoint = new boolean[65536];
|
||||
}
|
||||
|
||||
public void setText(StyledText text) {
|
||||
|
@ -128,6 +138,7 @@ public class CodeRuler {
|
|||
|
||||
if (source != null && lineNumber >= 0 && lineNumber < source.getLines().size()) {
|
||||
Line line = source.getLines().get(lineNumber);
|
||||
int address = line.getScope().getAddress();
|
||||
byte[] code = line.getBytes();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
@ -145,6 +156,7 @@ public class CodeRuler {
|
|||
else {
|
||||
gc.setBackground(canvas.getBackground());
|
||||
}
|
||||
gc.setFont((breakpoint[address] && code.length != 0) ? fontBold : font);
|
||||
gc.drawString(sb.toString(), leftMargin, y, true);
|
||||
}
|
||||
|
||||
|
@ -152,7 +164,10 @@ public class CodeRuler {
|
|||
}
|
||||
}
|
||||
|
||||
public void setFont(Font font) {
|
||||
public void setFont(Font font, Font boldFont) {
|
||||
this.font = font;
|
||||
this.fontBold = boldFont;
|
||||
|
||||
canvas.setFont(font);
|
||||
|
||||
GC gc = new GC(canvas);
|
||||
|
@ -172,4 +187,32 @@ public class CodeRuler {
|
|||
public void redraw() {
|
||||
canvas.redraw();
|
||||
}
|
||||
|
||||
public int[] getBreakpoints() {
|
||||
List<Integer> l = new ArrayList<Integer>();
|
||||
for (int i = 0; i < breakpoint.length; i++) {
|
||||
if (breakpoint[i]) {
|
||||
l.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
int[] result = new int[l.size()];
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
result[i] = l.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void toggleBreakpoint(int address) {
|
||||
breakpoint[address] = !breakpoint[address];
|
||||
}
|
||||
|
||||
public boolean isBreakpoint(int address) {
|
||||
return breakpoint[address];
|
||||
}
|
||||
|
||||
public void resetBreakpoints() {
|
||||
Arrays.fill(breakpoint, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ public class SourceViewer {
|
|||
ruler.setFont(font);
|
||||
ruler.setText(text);
|
||||
|
||||
codeRuler.setFont(font);
|
||||
codeRuler.setFont(font, fontBold);
|
||||
codeRuler.setText(text);
|
||||
|
||||
currentLine = 0;
|
||||
|
@ -374,7 +374,7 @@ public class SourceViewer {
|
|||
text.setCaretOffset(text.getCaretOffset());
|
||||
|
||||
ruler.setFont(font);
|
||||
codeRuler.setFont(font);
|
||||
codeRuler.setFont(font, fontBold);
|
||||
|
||||
container.getDisplay().asyncExec(new Runnable() {
|
||||
|
||||
|
@ -418,4 +418,18 @@ public class SourceViewer {
|
|||
styleMap.put(TokenId.NumberLiteral, new TextStyle(font, new Color(Display.getDefault(), 0xFF, 0x00, 0xFF), null));
|
||||
}
|
||||
|
||||
public void toggleBreakpoint(int address) {
|
||||
codeRuler.toggleBreakpoint(address);
|
||||
codeRuler.redraw();
|
||||
}
|
||||
|
||||
public boolean isBreakpoint(int address) {
|
||||
return codeRuler.isBreakpoint(address);
|
||||
}
|
||||
|
||||
public void resetBreakpoints() {
|
||||
codeRuler.resetBreakpoints();
|
||||
codeRuler.redraw();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1776,6 +1776,12 @@ public class Z80 {
|
|||
breakpointAt[address & 0xffff] = state;
|
||||
}
|
||||
|
||||
public final void setBreakpoints(int[] address, boolean state) {
|
||||
for (int i = 0; i < address.length; i++) {
|
||||
breakpointAt[address[i] & 0xffff] = state;
|
||||
}
|
||||
}
|
||||
|
||||
public void resetBreakpoints() {
|
||||
Arrays.fill(breakpointAt, false);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue