Preliminary breakpoint registration
This commit is contained in:
parent
f893ecd2cf
commit
2d048a74c0
4
makefile
4
makefile
|
@ -7,10 +7,10 @@ include_windows = jni-windows-include
|
||||||
# Default goal
|
# Default goal
|
||||||
.PHONY: default
|
.PHONY: default
|
||||||
default:
|
default:
|
||||||
@echo
|
@echo $(include_linux)
|
||||||
@echo "Planet Virtual Boy Emulator"
|
@echo "Planet Virtual Boy Emulator"
|
||||||
@echo " https://www.planetvb.com/"
|
@echo " https://www.planetvb.com/"
|
||||||
@echo " August 14, 2020"
|
@echo " October 13, 2020"
|
||||||
@echo
|
@echo
|
||||||
@echo "Intended build environment: Debian i386 or amd64"
|
@echo "Intended build environment: Debian i386 or amd64"
|
||||||
@echo " gcc-multilib"
|
@echo " gcc-multilib"
|
||||||
|
|
|
@ -51,15 +51,30 @@ public class Main {
|
||||||
// Begin application operations
|
// Begin application operations
|
||||||
new App(useNative);
|
new App(useNative);
|
||||||
|
|
||||||
/*
|
|
||||||
var brk = new Breakpoint();
|
var brk = new Breakpoint(null);
|
||||||
String exp = "([sp - 8] & 3) << 6 != 12.0 + r6 * ecr && [0x0500008C + r8] == 0";
|
|
||||||
System.out.println(exp);
|
String exp =
|
||||||
|
"([sp - 8] & 3) << 6 != 12.0 + r6 * ecr && [0x0500008C + r8] == 0";
|
||||||
|
System.out.println("\n" + exp);
|
||||||
if (brk.setCondition(exp))
|
if (brk.setCondition(exp))
|
||||||
System.out.println(brk.debug());
|
System.out.println(brk.debug());
|
||||||
else System.out.println(brk.getErrorCode() + "\t" +
|
else System.out.println(
|
||||||
brk.getErrorPosition() + ":" + brk.getErrorText());
|
brk.getErrorCode (Breakpoint.CONDITION) + "\t" +
|
||||||
*/
|
brk.getErrorPosition(Breakpoint.CONDITION) + ":" +
|
||||||
|
brk.getErrorText (Breakpoint.CONDITION)
|
||||||
|
);
|
||||||
|
|
||||||
|
exp = "123, 456 - 987 , f0-fffffff2";
|
||||||
|
System.out.println("\n" + exp);
|
||||||
|
if (brk.setAddresses(exp))
|
||||||
|
System.out.println(brk.test());
|
||||||
|
else System.out.println(
|
||||||
|
brk.getErrorCode (Breakpoint.ADDRESS) + "\t" +
|
||||||
|
brk.getErrorPosition(Breakpoint.ADDRESS) + ":" +
|
||||||
|
brk.getErrorText (Breakpoint.ADDRESS)
|
||||||
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,15 @@ public class Breakpoint {
|
||||||
|
|
||||||
// Instance fields
|
// Instance fields
|
||||||
private int[][] addresses; // Applicable address ranges
|
private int[][] addresses; // Applicable address ranges
|
||||||
|
private String addressText; // Un-processed address ranges
|
||||||
private String condition; // Un-processed condition
|
private String condition; // Un-processed condition
|
||||||
private int errCode; // Condition error code
|
private int[] errCode; // Error codes
|
||||||
private int errPosition; // Character of condition error
|
private int[] errPosition; // Character position of errors
|
||||||
private String errText; // Offending condition text
|
private String[] errText; // Offending error text
|
||||||
private boolean isEnabled; // Breakpoint is active
|
private boolean isEnabled; // Breakpoint is active
|
||||||
private String name; // Display name
|
private String name; // Display name
|
||||||
private Token[] tokens; // Evaluation tokens
|
private Token[] tokens; // Evaluation tokens
|
||||||
|
private Vue vue; // Containing emulation context
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +25,7 @@ public class Breakpoint {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Error codes
|
// Error codes
|
||||||
|
public static final int BADTYPE = -1;
|
||||||
public static final int NONE = 0;
|
public static final int NONE = 0;
|
||||||
public static final int BADLITERAL = 1;
|
public static final int BADLITERAL = 1;
|
||||||
public static final int BADTOKEN = 2;
|
public static final int BADTOKEN = 2;
|
||||||
|
@ -32,6 +35,10 @@ public class Breakpoint {
|
||||||
public static final int NESTING = 6;
|
public static final int NESTING = 6;
|
||||||
public static final int UNEXPECTED = 7;
|
public static final int UNEXPECTED = 7;
|
||||||
|
|
||||||
|
// Error types
|
||||||
|
public static final int ADDRESS = 0;
|
||||||
|
public static final int CONDITION = 1;
|
||||||
|
|
||||||
// Token types
|
// Token types
|
||||||
private static final int BINARY = 4;
|
private static final int BINARY = 4;
|
||||||
private static final int CLOSE = 6;
|
private static final int CLOSE = 6;
|
||||||
|
@ -91,7 +98,7 @@ public class Breakpoint {
|
||||||
private static final HashMap<String, Integer> SYMDEFS;
|
private static final HashMap<String, Integer> SYMDEFS;
|
||||||
|
|
||||||
// Functional symbol IDs
|
// Functional symbol IDs
|
||||||
private static final int ADDRESS = 0;
|
//private static final int ADDRESS = 0; // Same as error type
|
||||||
private static final int CODE = 1;
|
private static final int CODE = 1;
|
||||||
private static final int COND = 2;
|
private static final int COND = 2;
|
||||||
private static final int DISP = 3;
|
private static final int DISP = 3;
|
||||||
|
@ -298,14 +305,16 @@ public class Breakpoint {
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Default constructor
|
// Default constructor
|
||||||
public Breakpoint() {
|
public Breakpoint(Vue vue) {
|
||||||
addresses = new int[0][];
|
addresses = new int[0][];
|
||||||
|
addressText = "";
|
||||||
condition = "";
|
condition = "";
|
||||||
errCode = NONE;
|
errCode = new int [] { NONE, NONE };
|
||||||
errPosition = 0;
|
errPosition = new int [] { 0, 0 };
|
||||||
errText = "";
|
errText = new String[] { "", "" };
|
||||||
name = "";
|
name = "";
|
||||||
tokens = new Token[0];
|
tokens = new Token[0];
|
||||||
|
this.vue = vue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -366,24 +375,48 @@ public class Breakpoint {
|
||||||
return ret.toString();
|
return ret.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Produce a string representation of the internal address ranges
|
||||||
|
public String test() {
|
||||||
|
var ret = new StringBuilder();
|
||||||
|
for (int x = 0; x < addresses.length; x++) {
|
||||||
|
var range = addresses[x];
|
||||||
|
if (x > 0)
|
||||||
|
ret.append("\n");
|
||||||
|
ret.append(String.format("%08X", range[0]));
|
||||||
|
if (range[0] != range[1])
|
||||||
|
ret.append(String.format("-%08X", range[1]));
|
||||||
|
}
|
||||||
|
return ret.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Evaluate the condition against its emulation context
|
||||||
|
public boolean evaluate() {
|
||||||
|
return vue == null ? false : vue.evaluate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Retrieve the most recent input addresses
|
||||||
|
public String getAddresses() {
|
||||||
|
return addressText;
|
||||||
|
}
|
||||||
|
|
||||||
// Retrieve the most recent input condition
|
// Retrieve the most recent input condition
|
||||||
public String getCondition() {
|
public String getCondition() {
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the most recent error code
|
// Retrieve the most recent error code
|
||||||
public int getErrorCode() {
|
public int getErrorCode(int type) {
|
||||||
return errCode;
|
return type < 0 || type > 1 ? BADTYPE : errCode[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the most recent error character position
|
// Retrieve the most recent error character position
|
||||||
public int getErrorPosition() {
|
public int getErrorPosition(int type) {
|
||||||
return errPosition;
|
return type < 0 || type > 1 ? BADTYPE : errPosition[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the most recent error text
|
// Retrieve the most recent error text
|
||||||
public String getErrorText() {
|
public String getErrorText(int type) {
|
||||||
return errText;
|
return type < 0 || type > 1 ? null : errText[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the display name
|
// Retrieve the display name
|
||||||
|
@ -397,24 +430,137 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify and parse a list of address ranges
|
// Specify and parse a list of address ranges
|
||||||
public boolean setAddresses(int[][] addresses) {
|
public boolean setAddresses(String addresses) {
|
||||||
|
Integer first = null; // Value of first address
|
||||||
|
int mode = 0; // Processing state
|
||||||
|
var ranges = new ArrayList<int[]>(); // Output
|
||||||
|
int start = 0; // Position of address literal
|
||||||
|
int x = 0; // Input position
|
||||||
|
|
||||||
// Error checking
|
// Configure instance fields
|
||||||
if (addresses == null)
|
addressText = addresses == null ? addresses = "" : addresses;
|
||||||
return false;
|
|
||||||
for (var range : addresses)
|
|
||||||
if (range == null || range.length > 2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Accept the new address ranges
|
// Parse the input
|
||||||
this.addresses = new int[addresses.length][2];
|
var chars = (addresses + " ").toCharArray();
|
||||||
for (int x = 0; x < addresses.length; x++) {
|
for (x = 0; x < chars.length; x++) {
|
||||||
var range = addresses[x];
|
char c = chars[x];
|
||||||
this.addresses[x] = new int[] {
|
boolean white = c == ' ' || c == '\t';
|
||||||
range[0],
|
boolean digit =
|
||||||
range[range.length - 1]
|
c >= '0' && c <= '9' ||
|
||||||
};
|
c >= 'A' && c <= 'F' ||
|
||||||
|
c >= 'a' && c <= 'f'
|
||||||
|
;
|
||||||
|
|
||||||
|
// Before
|
||||||
|
if (mode == 0) {
|
||||||
|
|
||||||
|
// Ignore whitespace
|
||||||
|
if (white)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Begin an address
|
||||||
|
if (digit) {
|
||||||
|
start = x;
|
||||||
|
mode = 1; // During
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// During
|
||||||
|
else if (mode == 1) {
|
||||||
|
|
||||||
|
// Ignore digits
|
||||||
|
if (digit)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// The end of the address has been found
|
||||||
|
String text = new String(chars, start, x - start);
|
||||||
|
int addr = 0;
|
||||||
|
try { addr = (int) Long.parseLong(text, 16); }
|
||||||
|
|
||||||
|
// Could not parse the address
|
||||||
|
catch (Exception e) {
|
||||||
|
errCode [ADDRESS] = BADLITERAL;
|
||||||
|
errPosition[ADDRESS] = start + 1;
|
||||||
|
errText [ADDRESS] = text;
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Processed the first address
|
||||||
|
if (first == null)
|
||||||
|
first = addr;
|
||||||
|
|
||||||
|
// Processed the second address
|
||||||
|
else {
|
||||||
|
ranges.add(new int[] { first, addr });
|
||||||
|
first = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Begin searching for a delimiter
|
||||||
|
mode = 2; // After
|
||||||
|
x--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// After
|
||||||
|
else if (mode == 2) {
|
||||||
|
|
||||||
|
// Ignore whitespace
|
||||||
|
if (white)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Begin searching for the second address
|
||||||
|
if (c == '-' && first != null) {
|
||||||
|
mode = 0; // Before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// All addresses in the range have been processed
|
||||||
|
if (c == ',') {
|
||||||
|
if (first != null) {
|
||||||
|
ranges.add(new int[] { first, first });
|
||||||
|
first = null;
|
||||||
|
}
|
||||||
|
mode = 0; // Before
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invalid character
|
||||||
|
errCode [ADDRESS] = UNEXPECTED;
|
||||||
|
errPosition[ADDRESS] = x + 1;
|
||||||
|
errText [ADDRESS] = Character.toString(c);
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
|
return false;
|
||||||
|
} // x
|
||||||
|
|
||||||
|
// Unexpected end of input
|
||||||
|
if (mode == 0 && ranges.size() > 0) {
|
||||||
|
errCode [ADDRESS] = EARLYEOF;
|
||||||
|
errPosition[ADDRESS] = x + 1;
|
||||||
|
errText [ADDRESS] = "";
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// A one-address range was processed
|
||||||
|
if (first != null)
|
||||||
|
ranges.add(new int[] { first, first });
|
||||||
|
|
||||||
|
// Parsing was successful
|
||||||
|
this.addresses = ranges.toArray(new int[ranges.size()][]);
|
||||||
|
this.addressText = addresses;
|
||||||
|
errCode [ADDRESS] = NONE;
|
||||||
|
errPosition[ADDRESS] = 0;
|
||||||
|
errText [ADDRESS] = "";
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,20 +569,26 @@ public class Breakpoint {
|
||||||
|
|
||||||
// Configure instance fields
|
// Configure instance fields
|
||||||
this.condition = condition == null ? condition = "" : condition;
|
this.condition = condition == null ? condition = "" : condition;
|
||||||
errCode = NONE;
|
errCode [CONDITION] = NONE;
|
||||||
errPosition = 0;
|
errPosition[CONDITION] = 0;
|
||||||
errText = "";
|
errText [CONDITION] = "";
|
||||||
tokens = new Token[0];
|
tokens = new Token[0];
|
||||||
|
|
||||||
// Process the expression
|
// Process the expression
|
||||||
var tokens = parse();
|
var tokens = parse();
|
||||||
if (tokens == null || !validate(tokens))
|
if (tokens == null || !validate(tokens)) {
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
tree(tokens);
|
tree(tokens);
|
||||||
|
|
||||||
// The expression is empty
|
// The expression is empty
|
||||||
if (tokens.size() == 0)
|
if (tokens.size() == 0) {
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Produce an RPN-ordered list of tokens
|
// Produce an RPN-ordered list of tokens
|
||||||
var tok = tokens.remove(0);
|
var tok = tokens.remove(0);
|
||||||
|
@ -463,12 +615,16 @@ public class Breakpoint {
|
||||||
this.tokens = tokens.toArray(new Token[tokens.size()]);
|
this.tokens = tokens.toArray(new Token[tokens.size()]);
|
||||||
|
|
||||||
// The expression was successfully parsed
|
// The expression was successfully parsed
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specify the display name
|
// Specify the display name
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name == null ? "" : name;
|
this.name = name == null ? "" : name;
|
||||||
|
if (vue != null)
|
||||||
|
vue.update(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -477,12 +633,12 @@ public class Breakpoint {
|
||||||
// Package Methods //
|
// Package Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Evaluate the condition for an emulation context
|
// Evaluate the condition for a Java emulation context
|
||||||
boolean evaluate(JavaVue vue, int[] stack) {
|
boolean evaluate(JavaVue vue, int[] stack) {
|
||||||
|
|
||||||
// The condition is empty
|
// The condition is empty
|
||||||
if (tokens.length == 0)
|
if (tokens.length == 0)
|
||||||
return isEnabled && errCode == NONE;
|
return isEnabled && errCode[CONDITION] == NONE;
|
||||||
|
|
||||||
// Process tokens
|
// Process tokens
|
||||||
int size = 0;
|
int size = 0;
|
||||||
|
@ -505,21 +661,26 @@ public class Breakpoint {
|
||||||
int depth() {
|
int depth() {
|
||||||
|
|
||||||
// Error checking
|
// Error checking
|
||||||
if (errCode != NONE)
|
if (errCode[CONDITION] != NONE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Count the maximum size of the stack
|
// Count the maximum size of the stack
|
||||||
int max = 0;
|
int max = 0;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
for (var tok : tokens) switch (tok.type) {
|
for (var tok : tokens) switch (tok.type) {
|
||||||
case BINARY : size--; break;
|
case BINARY: size--; break;
|
||||||
case FLOAT : // Fallthrough
|
case FLOAT : // Fallthrough
|
||||||
case SYMBOL : // Fallthrough
|
case SYMBOL: // Fallthrough
|
||||||
case WORD : max = Math.max(max, ++size);
|
case WORD : max = Math.max(max, ++size);
|
||||||
}
|
}
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The breakpoint is being removed from its emulation context
|
||||||
|
void remove() {
|
||||||
|
vue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -586,9 +747,9 @@ public class Breakpoint {
|
||||||
|
|
||||||
// "x" cannot appear here
|
// "x" cannot appear here
|
||||||
if (isFloat || x != start + 1 || chars[start] != '0') {
|
if (isFloat || x != start + 1 || chars[start] != '0') {
|
||||||
errCode = UNEXPECTED;
|
errCode [CONDITION] = UNEXPECTED;
|
||||||
errPosition = x + 1;
|
errPosition[CONDITION] = x + 1;
|
||||||
errText = Character.toString(c);
|
errText [CONDITION] = Character.toString(c);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -602,9 +763,9 @@ public class Breakpoint {
|
||||||
|
|
||||||
// "." cannot appear here
|
// "." cannot appear here
|
||||||
if (isHex || isFloat) {
|
if (isHex || isFloat) {
|
||||||
errCode = UNEXPECTED;
|
errCode [CONDITION] = UNEXPECTED;
|
||||||
errPosition = x + 1;
|
errPosition[CONDITION] = x + 1;
|
||||||
errText = Character.toString(c);
|
errText [CONDITION] = Character.toString(c);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,9 +798,9 @@ public class Breakpoint {
|
||||||
|
|
||||||
// Could not parse the value
|
// Could not parse the value
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
errCode = BADLITERAL;
|
errCode [CONDITION] = BADLITERAL;
|
||||||
errPosition = x + 1;
|
errPosition[CONDITION] = x + 1;
|
||||||
errText = ret.text;
|
errText [CONDITION] = ret.text;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -684,9 +845,9 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The operator was not identified
|
// The operator was not identified
|
||||||
errCode = BADTOKEN;
|
errCode [CONDITION] = BADTOKEN;
|
||||||
errPosition = start + 1;
|
errPosition[CONDITION] = start + 1;
|
||||||
errText = Character.toString(chars[start]);
|
errText [CONDITION] = Character.toString(chars[start]);
|
||||||
return null;
|
return null;
|
||||||
} // x
|
} // x
|
||||||
|
|
||||||
|
@ -739,9 +900,9 @@ public class Breakpoint {
|
||||||
}
|
}
|
||||||
|
|
||||||
// The token is not recognized
|
// The token is not recognized
|
||||||
errCode = BADTOKEN;
|
errCode [CONDITION] = BADTOKEN;
|
||||||
errPosition = x + 1;
|
errPosition[CONDITION] = x + 1;
|
||||||
errText = ret.text;
|
errText [CONDITION] = ret.text;
|
||||||
return null;
|
return null;
|
||||||
} // x
|
} // x
|
||||||
|
|
||||||
|
@ -830,9 +991,9 @@ public class Breakpoint {
|
||||||
|
|
||||||
// The token is invalid
|
// The token is invalid
|
||||||
if (tok.id != NEGATE) {
|
if (tok.id != NEGATE) {
|
||||||
errCode = INVALID;
|
errCode [CONDITION] = INVALID;
|
||||||
errPosition = tok.start;
|
errPosition[CONDITION] = tok.start;
|
||||||
errText = tok.text;
|
errText [CONDITION] = tok.text;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -845,9 +1006,9 @@ public class Breakpoint {
|
||||||
// Nesting error
|
// Nesting error
|
||||||
if (tok.type == CLOSE &&
|
if (tok.type == CLOSE &&
|
||||||
(stack.empty() || stack.pop().id != tok.id)) {
|
(stack.empty() || stack.pop().id != tok.id)) {
|
||||||
errCode = NESTING;
|
errCode [CONDITION] = NESTING;
|
||||||
errPosition = tok.start;
|
errPosition[CONDITION] = tok.start;
|
||||||
errText = tok.text;
|
errText [CONDITION] = tok.text;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -862,9 +1023,9 @@ public class Breakpoint {
|
||||||
|
|
||||||
// A group was not closed
|
// A group was not closed
|
||||||
if (!stack.empty()) {
|
if (!stack.empty()) {
|
||||||
errCode = EARLYEOF;
|
errCode [CONDITION] = EARLYEOF;
|
||||||
errPosition = condition.length();
|
errPosition[CONDITION] = condition.length();
|
||||||
errText = stack.pop().text;
|
errText [CONDITION] = stack.pop().text;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Successfully parsed the condition
|
// Successfully parsed the condition
|
||||||
|
|
|
@ -87,12 +87,6 @@ class JavaVue extends Vue {
|
||||||
return Math.max(0, maxCycles);
|
return Math.max(0, maxCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the condition in a breakpoint
|
|
||||||
public boolean evaluate(Breakpoint brk) {
|
|
||||||
return brk != null ? false :
|
|
||||||
brk.evaluate(this, new int[brk.depth() * 2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the application break code
|
// Retrieve the application break code
|
||||||
public int getBreakCode() {
|
public int getBreakCode() {
|
||||||
return breakCode;
|
return breakCode;
|
||||||
|
@ -249,6 +243,11 @@ class JavaVue extends Vue {
|
||||||
// Package Methods //
|
// Package Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate the condition in a breakpoint
|
||||||
|
boolean evaluate(Breakpoint brk) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Exception break handler
|
// Exception break handler
|
||||||
int onException(Ecxeption exp) {
|
int onException(Ecxeption exp) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -84,10 +84,10 @@ JNIEXPORT jlong JNICALL Java_vue_NativeVue_construct
|
||||||
JNIEXPORT void JNICALL Java_vue_NativeVue_dispose
|
JNIEXPORT void JNICALL Java_vue_NativeVue_dispose
|
||||||
(JNIEnv *env, jobject vue, jlong handle) {
|
(JNIEnv *env, jobject vue, jlong handle) {
|
||||||
Core *core = *(Core **)&handle;
|
Core *core = *(Core **)&handle;
|
||||||
if (core->vue.pak.rom != NULL)
|
if (core->breakpoints != NULL) free(core->breakpoints);
|
||||||
free(core->vue.pak.rom);
|
if (core->stack != NULL) free(core->stack );
|
||||||
if (core->vue.pak.ram != NULL)
|
if (core->vue.pak.rom != NULL) free(core->vue.pak.rom);
|
||||||
free(core->vue.pak.ram);
|
if (core->vue.pak.ram != NULL) free(core->vue.pak.ram);
|
||||||
free(core);
|
free(core);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,13 +98,6 @@ JNIEXPORT jint JNICALL Java_vue_NativeVue_emulate
|
||||||
return vueEmulate(&core->vue, maxCycles);
|
return vueEmulate(&core->vue, maxCycles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Evaluate the condition in a breakpoint
|
|
||||||
JNIEXPORT jboolean JNICALL Java_vue_NativeVue_evaluate
|
|
||||||
(JNIEnv *env, jobject vue, jlong handle, jobject brk) {
|
|
||||||
Core *core = *(Core **)&handle;
|
|
||||||
return JNI_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Retrieve the application break code
|
// Retrieve the application break code
|
||||||
JNIEXPORT jint JNICALL Java_vue_NativeVue_getBreakCode
|
JNIEXPORT jint JNICALL Java_vue_NativeVue_getBreakCode
|
||||||
(JNIEnv *env, jobject vue, jlong handle) {
|
(JNIEnv *env, jobject vue, jlong handle) {
|
||||||
|
|
|
@ -34,11 +34,6 @@ class NativeVue extends Vue {
|
||||||
public int emulate(int maxCycles)
|
public int emulate(int maxCycles)
|
||||||
{ return emulate(handle, maxCycles); }
|
{ return emulate(handle, maxCycles); }
|
||||||
|
|
||||||
// Evaluate the condition in a breakpoint
|
|
||||||
private native boolean evaluate(long handle, Breakpoint brk);
|
|
||||||
public boolean evaluate(Breakpoint brk)
|
|
||||||
{ return evaluate(handle, brk); }
|
|
||||||
|
|
||||||
// Retrieve the application break code
|
// Retrieve the application break code
|
||||||
private native int getBreakCode(long handle);
|
private native int getBreakCode(long handle);
|
||||||
public int getBreakCode() { return getBreakCode(handle); }
|
public int getBreakCode() { return getBreakCode(handle); }
|
||||||
|
@ -94,4 +89,15 @@ class NativeVue extends Vue {
|
||||||
public boolean writeBytes(int address, byte[] src, int offset, int length)
|
public boolean writeBytes(int address, byte[] src, int offset, int length)
|
||||||
{ return writeBytes(handle, address, src, offset, length); }
|
{ return writeBytes(handle, address, src, offset, length); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Package Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate the condition in a breakpoint
|
||||||
|
boolean evaluate(Breakpoint brk) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
package vue;
|
package vue;
|
||||||
|
|
||||||
|
// Java imports
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
// Template for emulation core implementations
|
// Template for emulation core implementations
|
||||||
public abstract class Vue {
|
public abstract class Vue {
|
||||||
|
|
||||||
|
// Instance fields
|
||||||
|
ArrayList<Breakpoint> breakpoints; // Current breakpoints
|
||||||
|
|
||||||
// Static fields
|
// Static fields
|
||||||
private static String nativeID = null; // ID of loaded native library
|
private static String nativeID = null; // ID of loaded native library
|
||||||
|
|
||||||
|
@ -152,19 +158,53 @@ public abstract class Vue {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Constructors //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Default constructor
|
||||||
|
Vue() {
|
||||||
|
breakpoints = new ArrayList<Breakpoint>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Public Methods //
|
// Public Methods //
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Produce a new breakpoint and add it to the collection
|
||||||
|
public Breakpoint breakpoint() {
|
||||||
|
var brk = new Breakpoint(this);
|
||||||
|
breakpoints.add(brk);
|
||||||
|
return brk;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Produce an array of the current breakpoint collection
|
||||||
|
public Breakpoint[] listBreakpoints() {
|
||||||
|
return breakpoints.toArray(new Breakpoint[breakpoints.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove a breakpoint from the collection
|
||||||
|
public boolean remove(Breakpoint brk) {
|
||||||
|
if (!breakpoints.remove(brk))
|
||||||
|
return false;
|
||||||
|
brk.remove();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Abstract Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Release any used resources
|
// Release any used resources
|
||||||
public abstract void dispose();
|
public abstract void dispose();
|
||||||
|
|
||||||
// Process the simulation
|
// Process the simulation
|
||||||
public abstract int emulate(int maxCycles);
|
public abstract int emulate(int maxCycles);
|
||||||
|
|
||||||
// Evaluate the condition in a breakpoint
|
|
||||||
public abstract boolean evaluate(Breakpoint brk);
|
|
||||||
|
|
||||||
// Retrieve the application break code
|
// Retrieve the application break code
|
||||||
public abstract int getBreakCode();
|
public abstract int getBreakCode();
|
||||||
|
|
||||||
|
@ -200,4 +240,17 @@ public abstract class Vue {
|
||||||
public abstract boolean writeBytes(int address, byte[] src, int offset,
|
public abstract boolean writeBytes(int address, byte[] src, int offset,
|
||||||
int length);
|
int length);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
// Package Methods //
|
||||||
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
// Evaluate the condition in a breakpoint
|
||||||
|
abstract boolean evaluate(Breakpoint brk);
|
||||||
|
|
||||||
|
// A breakpoint has been updated
|
||||||
|
void update(Breakpoint brk) {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue