Skip to content

Commit

Permalink
Fixed all bugs with labels.
Browse files Browse the repository at this point in the history
  • Loading branch information
RuneTekk committed Apr 15, 2012
1 parent ddbd6e4 commit 668a261
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 24 deletions.
2 changes: 1 addition & 1 deletion nbproject/private/private.properties
@@ -1,4 +1,4 @@
application.args=-c ./asm/sys.dasm ./asm/sys.bin -e ./asm/sys.bin
application.args=-c ./asm/xtea.dasm ./asm/xtea.bin -e ./asm/xtea.bin -d ./asm/xtea.bin ./asm/xtea.dump
compile.on.save=true
do.depend=false
do.jar=true
Expand Down
41 changes: 26 additions & 15 deletions src/org/sini/Asm.java
Expand Up @@ -77,13 +77,14 @@ private static int lookupInstruction(String str) {
/**
* Looks up an operator in the operators array.
* @param str The string to lookup.
* @param The value is represented as a label.
* @return The opcode of the operator.
*/
private static int lookupValue(String str) {
private static int lookupValue(String str, boolean isLabel) {
Matcher matcher = DECIMAL_PATTERN.matcher(str);
if(matcher.find()) {
int value = Integer.parseInt(matcher.group());
if(value >= 0x0 && value <= 0x1F)
if(value >= 0x0 && value <= 0x1F && !isLabel)
return value + 0x20;
else
str = matcher.replaceAll("%nw%");
Expand Down Expand Up @@ -124,16 +125,17 @@ public int[] assemble(String code) {
if(name.length() < 4)
throw new RuntimeException("Illegal label, " + '\'' + name + '\'' + ", on line " + getLineNumber(code, matcher.start()));
code = code.replaceFirst(matcher.group(), ":" + labelOffset);
int duplicateIndex = -1;
if((duplicateIndex = code.indexOf(matcher.group())) > -1)
throw new RuntimeException("Duplicate label, " + '\'' + name + '\'' + ", on line " + getLineNumber(code, duplicateIndex));
code = code.replaceAll(name, "#" + labelOffset++ + "#");
if(code.matches(matcher.group() + " "))
throw new RuntimeException("Duplicate label, " + '\'' + name + '\'' + ", on line " + getLineNumber(code, code.indexOf(matcher.group())));
Matcher referenceMatcher = Pattern.compile(name + "[\n ]").matcher(code);
while(referenceMatcher.find()) {
code = code.substring(0, referenceMatcher.start()) + "#" + labelOffset++ + "#" + code.substring(referenceMatcher.end() - 1);
}
}
matcher = HEXADECIMAL_PATTERN.matcher(code);
while(matcher.find()) {
while((matcher = HEXADECIMAL_PATTERN.matcher(code)).find()) {
String value = matcher.group(1);
try {
code = matcher.replaceAll("" + Integer.parseInt(value, 16));
try {
code = code.substring(0, matcher.start()) + Integer.valueOf(value, 16) + code.substring(matcher.end());
} catch(Exception ex) {
throw new RuntimeException("Invalid hexidecimal literal, " + '\'' + matcher.group() + '\'' + ", on line " + getLineNumber(code, matcher.start(1)));
}
Expand All @@ -143,7 +145,8 @@ public int[] assemble(String code) {
matcher = INSTRUCTION_PATTERN.matcher(code);
while(matcher.find()) {
if(matcher.group().startsWith(":")) {
labels[Integer.parseInt(matcher.group().substring(1))] = counter;
int labelId = Integer.parseInt(matcher.group().substring(1));
labels[labelId] = counter;
continue;
}
int insnOpcode = lookupInstruction(matcher.group());
Expand All @@ -156,9 +159,16 @@ public int[] assemble(String code) {
for(int argument = 0; argument < arguments; argument++) {
if(!matcher.find())
throw new RuntimeException("Expected argument " + (argument + 1) + " after " + Ops.OP_NAMES[insnOpcode] + " on line " + getLineNumber(code, code.length()));
int valueOpcode = lookupValue(matcher.group());
String matcherValue = matcher.group();
Matcher markerMatcher = MARKER_PATTERN.matcher(matcherValue);
boolean isLabel = false;
if((isLabel = markerMatcher.find())) {
counter++;
continue;
}
int valueOpcode = lookupValue(matcherValue, isLabel);
if(valueOpcode < 0)
throw new RuntimeException("Unknown value, " + '\'' + matcher.group() + '\'' + ", on line " + getLineNumber(code, matcher.start(0)));
throw new RuntimeException("Unknown value, " + '\'' + matcher.group() + '\'' + ", on line " + getLineNumber(code, matcher.start(0)));
if(Ops.V_NAMES[valueOpcode].indexOf("%nw%") > -1) {
Matcher decimalMatcher = DECIMAL_PATTERN.matcher(matcher.group());
if(!decimalMatcher.find())
Expand All @@ -182,9 +192,10 @@ public int[] assemble(String code) {
matcher.find();
String matcherValue = matcher.group();
Matcher markerMatcher = MARKER_PATTERN.matcher(matcherValue);
if(markerMatcher.find())
boolean isLabel = false;
if((isLabel = markerMatcher.find()))
matcherValue = markerMatcher.replaceAll("" + labels[Integer.parseInt(markerMatcher.group(1))]);
int valueOpcode = lookupValue(matcherValue);
int valueOpcode = lookupValue(matcherValue, isLabel);
if(Ops.V_NAMES[valueOpcode].indexOf("%nw%") > -1) {
Matcher decimalMatcher = DECIMAL_PATTERN.matcher(matcherValue);
decimalMatcher.find();
Expand Down
7 changes: 5 additions & 2 deletions src/org/sini/Cpu.java
@@ -1,6 +1,5 @@
package org.sini;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.IOException;
import static org.sini.Ops.*;
Expand Down Expand Up @@ -56,6 +55,11 @@ public final class Cpu {
*/
Cell[] r;

/**
* The {@link Cpu} will print out debugging information.
*/
boolean debug;

/**
* Initializes this {@link Cpu}.
*/
Expand Down Expand Up @@ -95,7 +99,6 @@ public void execute() {
while(true) {
int op = m[r[PC].v++].v;
if((op & 0xF) != 0) {

Object a = getValue(op >>> 4 & 0x3F, true);
Object b = getValue(op >>> 10 & 0x3F, true);
if(!(a instanceof Cell)) {
Expand Down
22 changes: 21 additions & 1 deletion src/org/sini/Dasm.java
@@ -1,12 +1,31 @@
package org.sini;

import java.io.IOException;
import java.io.InputStream;

/**
* Dasm.java
* @version 1.0.0
* @author RuneTekk Development (SiniSoul)
*/
public final class Dasm {

/**
* Mount the memory of a program onto the memory of the {@link Cpu}.
* @param is The {@link InputStream} to get the code from to disassemble.
*/
public String disassemble(InputStream is) throws IOException {
int available = is.available();
if(available % 2 != 0)
throw new IOException();
int[] memory = new int[available/2];
int offset = 0;
while((available -= 2) >= 0) {
memory[offset++] = is.read() << 8 | is.read();
}
return disassemble(memory);
}

/**
* Disassembles a programs instructions into an ASM code string.
* @param memory The program memory.
Expand All @@ -17,6 +36,7 @@ public String disassemble(int[] memory) {
int position = 0;
int tabulate = 0;
while(position < memory.length) {
int oldPosition = position;
int opcodeValue = memory[position++];
int insnOpcode = (opcodeValue & 0xF) != 0 ? opcodeValue & 0xF : opcodeValue & 0x3F0;
int arguments = (insnOpcode & 0xF) == 0 ? 1 : 2;
Expand All @@ -35,7 +55,7 @@ public String disassemble(int[] memory) {
code += valueName;
}
tabulate = doTabulate ? tabulate + 1 : tabulate;
code += position < memory.length ? "\n" : "";
code += " 0x" + Integer.toHexString(oldPosition) + (position < memory.length ? "\n" : "");
}
return code;
}
Expand Down
41 changes: 36 additions & 5 deletions src/org/sini/Main.java
Expand Up @@ -43,7 +43,6 @@ public static void main(String[] args) {
if(argument.equals("c") || argument.equals("compile")) {
if(args.length - i < 2)
throw new RuntimeException("Usage: -c <source file> <destination file>...");
System.out.println("Compiling " + args[i] + " to " + args[i + 1] + "...");
InputStream is = null;
try {
is = new FileInputStream(args[i++]);
Expand All @@ -60,7 +59,7 @@ public static void main(String[] args) {
OutputStream os = null;
try {
os = new FileOutputStream(args[i++]);
for(int insn : insns) {
for(int insn : insns) {
os.write(insn >> 8);
os.write(insn);
}
Expand All @@ -70,23 +69,55 @@ public static void main(String[] args) {
throw new RuntimeException("Exception thrown while writing the output file: \n\t" + ex);
}
System.out.println("Compiled " + insns.length + " instructions to " + args[i - 1] + "...");
} else if(argument.equals("d") || argument.equals("disasm")) {
if(args.length - i < 2)
throw new RuntimeException("Usage: -d <source file> <destination file>...");
InputStream is = null;
try {
is = new FileInputStream(args[i++]);
} catch(Exception ex) {
throw new RuntimeException("Exception thrown while opening source stream: \n\t" + ex);
}
Dasm asm = new Dasm();
String insns = null;
try {
insns = asm.disassemble(is);
} catch(Exception ex) {
throw new RuntimeException("Exception thrown while disassembling: \n\t" + ex);
}
OutputStream os = null;
try {
os = new FileOutputStream(args[i++]);
os.write(insns.getBytes());
os.flush();
os.close();
} catch(Exception ex) {
throw new RuntimeException("Exception thrown while writing the output file: \n\t" + ex);
}
System.out.println("Disassembled instructions to " + args[i - 1] + "...");
} else if(argument.equals("e") || argument.equals("execute")) {
if(args.length - i < 1)
throw new RuntimeException("Usage: -e <source file>...");
System.out.println("Executing " + args[i] + "...");
InputStream is = null;
try {
is = new FileInputStream(args[i++]);
} catch(Exception ex) {
throw new RuntimeException("Exception thrown while opening source stream: \n\t" + ex);
}
boolean debug = false;
if(args[i].startsWith("--"))
if(args[i++].equals("--d") || args[i - 1].equals("--debug"))
debug = true;
else
throw new RuntimeException("Expected --d or --debug flag...");
Cpu cpu = new Cpu();
cpu.debug = debug;
try {
cpu.execute(is);
} catch(Exception ex) {
throw new RuntimeException("Exception thrown while executing: \n\t" + ex);
throw new RuntimeException("Exception thrown while executing: \n\t" + ex);
}
System.out.println(args[i - 1] + " took " + cpu.r[Cpu.C].v + " cycles...");
System.out.println("The program took a total of " + cpu.r[Cpu.C].v + " cycles...");
} else
throw new RuntimeException("Unknown command argument: " + argument);
}
Expand Down

0 comments on commit 668a261

Please sign in to comment.