Implemented debugger breakpoints

master
Marco Maccaferri 2019-01-10 10:35:35 +01:00
rodzic 0f6f75c31b
commit 3e9b6dcdc4
4 zmienionych plików z 195 dodań i 32 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);
}
}

Wyświetl plik

@ -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();
}
}

Wyświetl plik

@ -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);
}