|
@@ -42,6 +42,7 @@ import de.mcs.tools.sps.mnemonic.HARDWARE;
|
|
import de.mcs.tools.sps.mnemonic.JMP;
|
|
import de.mcs.tools.sps.mnemonic.JMP;
|
|
import de.mcs.tools.sps.mnemonic.Mnemonic;
|
|
import de.mcs.tools.sps.mnemonic.Mnemonic;
|
|
import de.mcs.tools.sps.mnemonic.MnemonicFactory;
|
|
import de.mcs.tools.sps.mnemonic.MnemonicFactory;
|
|
|
|
+import de.mcs.tools.sps.mnemonic.RJMP;
|
|
import de.mcs.utils.jsap.Command;
|
|
import de.mcs.utils.jsap.Command;
|
|
import de.mcs.utils.jsap.CommandlineProcessor;
|
|
import de.mcs.utils.jsap.CommandlineProcessor;
|
|
import de.mcs.utils.jsap.FileOption;
|
|
import de.mcs.utils.jsap.FileOption;
|
|
@@ -101,6 +102,8 @@ public class SPSAssembler {
|
|
* @throws IOException
|
|
* @throws IOException
|
|
*/
|
|
*/
|
|
public static void main(String[] args) throws IOException, SyntaxError {
|
|
public static void main(String[] args) throws IOException, SyntaxError {
|
|
|
|
+ destination = HARDWARE.HOLTEK;
|
|
|
|
+
|
|
CommandlineProcessor.processCommandline(SPSAssembler.class, args);
|
|
CommandlineProcessor.processCommandline(SPSAssembler.class, args);
|
|
|
|
|
|
if (!source.exists()) {
|
|
if (!source.exists()) {
|
|
@@ -126,26 +129,45 @@ public class SPSAssembler {
|
|
System.err.println(e.getMessage());
|
|
System.err.println(e.getMessage());
|
|
System.exit(-1);
|
|
System.exit(-1);
|
|
}
|
|
}
|
|
|
|
+ // Checking destination
|
|
|
|
+ for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
|
|
|
|
+ Mnemonic mnemonic = iterator.next();
|
|
|
|
+ if (!mnemonic.allowedHardware().contains(destination)) {
|
|
|
|
+ throw new SyntaxError(mnemonic.getLineNumber(),
|
|
|
|
+ String.format("the mnemonic \"%s\" with the argument \"%s\" is not availble on the choosen hardware \"%s\"",
|
|
|
|
+ mnemonic.getName(), mnemonic.getArgument(), destination.name()));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
System.out.println("parsing line numbers");
|
|
System.out.println("parsing line numbers");
|
|
|
|
+ int address = 0;
|
|
for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
|
|
for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
|
|
Mnemonic mnemonic = iterator.next();
|
|
Mnemonic mnemonic = iterator.next();
|
|
if (mnemonic instanceof JMP) {
|
|
if (mnemonic instanceof JMP) {
|
|
-
|
|
|
|
|
|
+ if (mnemonic.isLabel()) {
|
|
|
|
+ processJMP(mnemonic);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (mnemonic instanceof RJMP) {
|
|
|
|
+ if (mnemonic.isLabel()) {
|
|
|
|
+ processRJMP(address, mnemonic);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ address++;
|
|
}
|
|
}
|
|
|
|
|
|
System.out.println("Mnemonics");
|
|
System.out.println("Mnemonics");
|
|
int pos = 0;
|
|
int pos = 0;
|
|
for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
|
|
for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
|
|
Mnemonic mnemonic = iterator.next();
|
|
Mnemonic mnemonic = iterator.next();
|
|
- System.out.printf("%03d: %s\r\n", pos, mnemonic.toString());
|
|
|
|
|
|
+ System.out.printf("0x%03x: %s\r\n", pos, mnemonic.toString());
|
|
pos++;
|
|
pos++;
|
|
}
|
|
}
|
|
|
|
|
|
System.out.println();
|
|
System.out.println();
|
|
System.out.println("labels");
|
|
System.out.println("labels");
|
|
for (Entry<String, Integer> entry : labels.entrySet()) {
|
|
for (Entry<String, Integer> entry : labels.entrySet()) {
|
|
- System.out.printf("%s: %03d\r\n", entry.getKey(), entry.getValue());
|
|
|
|
|
|
+ System.out.printf("%s: 0x%03x\r\n", entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
|
|
IntelHex intelHex = new IntelHex();
|
|
IntelHex intelHex = new IntelHex();
|
|
@@ -160,6 +182,35 @@ public class SPSAssembler {
|
|
output.close();
|
|
output.close();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private static void processJMP(Mnemonic mnemonic) throws SyntaxError {
|
|
|
|
+ String label = mnemonic.getArgument();
|
|
|
|
+ if (!labels.containsKey(label)) {
|
|
|
|
+ throw new SyntaxError(mnemonic.getLineNumber(),
|
|
|
|
+ String.format("used label %s on mnemonic \"%s\" is not defined.", label, mnemonic.getName()));
|
|
|
|
+ }
|
|
|
|
+ int lineNumber = labels.get(label);
|
|
|
|
+ int page = lineNumber / 16;
|
|
|
|
+ lineNumber = lineNumber % 16;
|
|
|
|
+ mnemonic.setArgument(Integer.toString(lineNumber));
|
|
|
|
+ mnemonic.checkArgument();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void processRJMP(int address, Mnemonic mnemonic) throws SyntaxError {
|
|
|
|
+ String label = mnemonic.getArgument();
|
|
|
|
+ if (!labels.containsKey(label)) {
|
|
|
|
+ throw new SyntaxError(mnemonic.getLineNumber(),
|
|
|
|
+ String.format("used label %s on mnemonic \"%s\" is not defined.", label, mnemonic.getName()));
|
|
|
|
+ }
|
|
|
|
+ int lineNumber = labels.get(label);
|
|
|
|
+ lineNumber = address - lineNumber;
|
|
|
|
+ if (lineNumber < 0) {
|
|
|
|
+ throw new SyntaxError(mnemonic.getLineNumber(),
|
|
|
|
+ String.format("label %s defined after mnemonic \"%s\". JMP can only step back!", label, mnemonic.getName()));
|
|
|
|
+ }
|
|
|
|
+ mnemonic.setArgument(Integer.toString(lineNumber));
|
|
|
|
+ mnemonic.checkArgument();
|
|
|
|
+ }
|
|
|
|
+
|
|
private static void parseLine(int srcLineNumber, String line) throws SyntaxError {
|
|
private static void parseLine(int srcLineNumber, String line) throws SyntaxError {
|
|
if (line.startsWith(":")) {
|
|
if (line.startsWith(":")) {
|
|
String label = getLabel(line);
|
|
String label = getLabel(line);
|