Browse Source

starting TXT output for easier field programming.

Wilfried Klaas 6 years ago
parent
commit
a87ed81944
2 changed files with 252 additions and 188 deletions
  1. 31 0
      src/main/java/de/mcs/tools/sps/FORMAT.java
  2. 221 188
      src/main/java/de/mcs/tools/sps/SPSAssembler.java

+ 31 - 0
src/main/java/de/mcs/tools/sps/FORMAT.java

@@ -0,0 +1,31 @@
+/**
+ * MCS Media Computer Software
+ * <one line to give the program's name and a brief idea of what it does.>
+ * Copyright (C) 2018 by Wilfried Klaas
+ * Project: SPSEmulator
+ * File: FORMAT.java
+ * EMail: W.Klaas@gmx.de
+ * Created: 02.12.2018 wklaa
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+package de.mcs.tools.sps;
+
+/**
+ * @author wklaa
+ *
+ */
+public enum FORMAT {
+	HEX, TPSTXT
+}

+ 221 - 188
src/main/java/de/mcs/tools/sps/SPSAssembler.java

@@ -21,10 +21,13 @@
  */
 package de.mcs.tools.sps;
 
+import java.io.BufferedWriter;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.FileWriter;
 import java.io.IOException;
+import java.io.Writer;
 import java.nio.charset.Charset;
 import java.nio.file.Files;
 import java.util.ArrayList;
@@ -56,214 +59,244 @@ import de.mcs.utils.jsap.SwitchOption;
 @Command(help = "SPS Assembler \r\n usage java -jar SPSEmulator-x.x.x.jar <options>")
 public class SPSAssembler {
 
-  private static File source;
-  private static HARDWARE destination;
-  private static int lineNumber;
-  private static int srcLineNumber;
-  private static Map<String, Integer> labels = new HashMap<>();
-  private static boolean inBlockComment;
-  private static List<Mnemonic> mnemonics = new ArrayList<>();
-  private static File destinationFile;
+	private static File source;
+	private static HARDWARE destination;
+	private static int lineNumber;
+	private static int srcLineNumber;
+	private static Map<String, Integer> labels = new HashMap<>();
+	private static boolean inBlockComment;
+	private static List<Mnemonic> mnemonics = new ArrayList<>();
+	private static File destinationFile;
+	private static FORMAT outputFormat;
 
-  /**
-   * 
-   */
-  public SPSAssembler() {
-    // TODO Auto-generated constructor stub
-  }
+	/**
+	 * 
+	 */
+	public SPSAssembler() {
+		// TODO Auto-generated constructor stub
+	}
 
-  @SwitchOption(shortKey = 'h', longKey = "help", name = "help", help = "show this help page", required = false, defaultValue = false)
-  public static void doHelp(boolean value) {
-    if (value) {
-      CommandlineProcessor.showHelp();
-      System.exit(0);
-    }
-  }
+	@SwitchOption(shortKey = 'h', longKey = "help", name = "help", help = "show this help page", required = false, defaultValue = false)
+	public static void doHelp(boolean value) {
+		if (value) {
+			CommandlineProcessor.showHelp();
+			System.exit(0);
+		}
+	}
 
-  @StringOption(shortKey = 'd', longKey = "destination", name = "destination system", defaultValue = "HOLTEK", help = "the destination system to compile to.", required = false)
-  public static void setDestinationSystem(String value) {
-    destination = HARDWARE.valueOf((value.toUpperCase()));
-  }
+	@StringOption(shortKey = 'f', longKey = "format", name = "format", defaultValue = "HEX", help = "the output format. HEX: IntelHEX, TPSTXT: TPS programming text", required = false)
+	public static void setOutputFormat(String value) {
+		outputFormat = FORMAT.valueOf((value.toUpperCase()));
+	}
 
-  @FileOption(index = 1, name = "source file", help = "source file to compile", required = true, mustExists = true)
-  public static void setSourceFile(File file) {
-    source = file;
-  }
+	@StringOption(shortKey = 'd', longKey = "hardware", name = "hardware system", defaultValue = "HOLTEK", help = "the hardware system to compile to. Passible options are: HOLTEK, ATMEGA8, ARDUINOSPS, TINYSPS", required = false)
+	public static void setDestinationSystem(String value) {
+		destination = HARDWARE.valueOf((value.toUpperCase()));
+	}
 
-  @FileOption(index = 2, name = "destination file", help = "destination file to compile to", required = false)
-  public static void setDestinationFile(File file) {
-    if (file != null) {
-      destinationFile = file;
-    }
-  }
+	@FileOption(index = 1, name = "source file", help = "source file to compile", required = true, mustExists = true)
+	public static void setSourceFile(File file) {
+		source = file;
+	}
 
-  /**
-   * @param args
-   * @throws IOException
-   */
-  public static void main(String[] args) throws IOException, SyntaxError {
-    destination = HARDWARE.HOLTEK;
+	@FileOption(index = 2, name = "destination file", help = "destination file to compile to", required = false)
+	public static void setDestinationFile(File file) {
+		if ((file != null) && !file.getName().equals("")) {
+			destinationFile = file;
+		}
+	}
 
-    CommandlineProcessor.processCommandline(SPSAssembler.class, args);
+	/**
+	 * @param args
+	 * @throws IOException
+	 */
+	public static void main(String[] args) throws IOException, SyntaxError {
+		destination = HARDWARE.HOLTEK;
 
-    if (!source.exists()) {
-      throw new FileNotFoundException(String.format("source file not found. %s", source.getAbsolutePath()));
-    }
-    System.out.printf("source file: %s \r\n", source.getName());
-    if (destinationFile == null) {
-      String name = source.getName();
-      name = name.substring(0, source.getName().lastIndexOf("."));
-      destinationFile = new File(source.getParentFile(), name + ".hex");
-    }
-    System.out.printf("destination file: %s \r\n", destinationFile.getName());
-    System.out.println();
+		CommandlineProcessor.processCommandline(SPSAssembler.class, args);
 
-    try {
-      List<String> sourceFile = Files.readAllLines(source.toPath(), Charset.forName("UTF-8"));
-      for (String line : sourceFile) {
-        srcLineNumber++;
-        parseLine(srcLineNumber, line);
-      }
+		if (!source.exists()) {
+			throw new FileNotFoundException(String.format("source file not found. %s", source.getAbsolutePath()));
+		}
+		System.out.printf("source file: %s \r\n", source.getName());
+		if (destinationFile == null) {
+			String name = source.getName();
+			name = name.substring(0, source.getName().lastIndexOf("."));
+			String ext = ".hex";
+			if (outputFormat.equals(FORMAT.TPSTXT)) {
+				ext = ".txt";
+			}
+			destinationFile = new File(source.getParentFile(), name + ext);
+		}
+		System.out.printf("destination file: %s \r\n", destinationFile.getName());
+		System.out.println();
 
-    } catch (SyntaxError e) {
-      System.err.println(e.getMessage());
-      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()));
-      }
-    }
+		try {
+			List<String> sourceFile = Files.readAllLines(source.toPath(), Charset.forName("UTF-8"));
+			for (String line : sourceFile) {
+				srcLineNumber++;
+				parseLine(srcLineNumber, line);
+			}
 
-    System.out.println("parsing line numbers");
-    int address = 0;
-    for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
-      Mnemonic mnemonic = iterator.next();
-      if (mnemonic instanceof JMP) {
-        if (mnemonic.isLabel()) {
-          processJMP(mnemonic);
-        }
-      }
-      if (mnemonic instanceof RJMP) {
-        if (mnemonic.isLabel()) {
-          processRJMP(address, mnemonic);
-        }
-      }
-      address++;
-    }
+		} catch (SyntaxError e) {
+			System.err.println(e.getMessage());
+			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("Mnemonics");
-    int pos = 0;
-    for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
-      Mnemonic mnemonic = iterator.next();
-      System.out.printf("0x%03x: %s\r\n", pos, mnemonic.toString());
-      pos++;
-    }
+		System.out.println("parsing line numbers");
+		int address = 0;
+		for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
+			Mnemonic mnemonic = iterator.next();
+			if (mnemonic instanceof JMP) {
+				if (mnemonic.isLabel()) {
+					processJMP(mnemonic);
+				}
+			}
+			if (mnemonic instanceof RJMP) {
+				if (mnemonic.isLabel()) {
+					processRJMP(address, mnemonic);
+				}
+			}
+			address++;
+		}
 
-    System.out.println();
-    System.out.println("labels");
-    for (Entry<String, Integer> entry : labels.entrySet()) {
-      System.out.printf("%s: 0x%03x\r\n", entry.getKey(), entry.getValue());
-    }
+		System.out.println("Mnemonics");
+		int pos = 0;
+		for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
+			Mnemonic mnemonic = iterator.next();
+			System.out.printf("0x%03x: %s\r\n", pos, mnemonic.toString());
+			pos++;
+		}
 
-    IntelHex intelHex = new IntelHex();
-    byte[] data = new byte[mnemonics.size()];
-    int i = 0;
-    for (Mnemonic mnemonic : mnemonics) {
-      data[i] = (byte) mnemonic.getByte();
-      i++;
-    }
-    FileOutputStream output = new FileOutputStream(destinationFile);
-    intelHex.writeHexStream(output, data);
-    output.close();
-  }
+		System.out.println();
+		System.out.println("labels");
+		for (Entry<String, Integer> entry : labels.entrySet()) {
+			System.out.printf("%s: 0x%03x\r\n", entry.getKey(), entry.getValue());
+		}
 
-  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();
-  }
+		if (outputFormat.equals(FORMAT.HEX)) {
+			outputHEX();
+		}
+		if (outputFormat.equals(FORMAT.TPSTXT)) {
+			outputTPSTXT();
+		}
+	}
 
-  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 outputTPSTXT() {
+		try (Writer writer = new BufferedWriter(new FileWriter(destinationFile))) {
+			int address = 0;
+			for (Mnemonic mnemonic : mnemonics) {
+				writer.write(String.format("0x%03x\r\n", address));
+				mnemonic.getByte();
+				address++;
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+		}
+	}
 
-  private static void parseLine(int srcLineNumber, String line) throws SyntaxError {
-    if (line.startsWith(":")) {
-      String label = getLabel(line);
-      if (labels.containsKey(label)) {
-        throw new SyntaxError(srcLineNumber,
-            String.format("Label \"%s\" already definied in line %d.", label, labels.get(label)));
-      }
-      labels.put(label, lineNumber);
-    } else {
-      Mnemonic mnemonic = getMnemonic(line);
-      if (mnemonic != null) {
-        lineNumber++;
-        mnemonics.add(mnemonic);
-      }
-    }
-  }
+	private static void outputHEX() throws FileNotFoundException, IOException {
+		IntelHex intelHex = new IntelHex();
+		byte[] data = new byte[mnemonics.size()];
+		int i = 0;
+		for (Mnemonic mnemonic : mnemonics) {
+			data[i] = (byte) mnemonic.getByte();
+			i++;
+		}
+		FileOutputStream output = new FileOutputStream(destinationFile);
+		intelHex.writeHexStream(output, data);
+		output.close();
+	}
 
-  private static Mnemonic getMnemonic(String line) throws SyntaxError {
-    String newLine = stripComments(line);
-    if (StringUtils.isNotEmpty(newLine)) {
-      Mnemonic mnemonic = MnemonicFactory.getMnemonic(newLine, srcLineNumber);
-      return mnemonic;
-    }
-    return null;
-  }
+	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 = (Integer) labels.get(label);
+		int page = lineNumber / 16;
+		lineNumber = lineNumber % 16;
+		mnemonic.setArgument(Integer.toString(lineNumber));
+		mnemonic.checkArgument();
+	}
 
-  private static String stripComments(String line) {
-    if (line.indexOf("*/") >= 0) {
-      inBlockComment = false;
-      return null;
-    }
-    if (inBlockComment) {
-      return null;
-    }
-    if (line.indexOf(";") >= 0) {
-      line = line.substring(0, line.indexOf(";")).trim();
-      return line;
-    }
-    if (line.startsWith("/*")) {
-      inBlockComment = true;
-      return null;
-    }
-    return line.trim();
-  }
+	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 = (Integer) 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 String getLabel(String line) {
-    line = stripComments(line);
-    return line;
-  }
+	private static void parseLine(int srcLineNumber, String line) throws SyntaxError {
+		if (line.startsWith(":")) {
+			String label = getLabel(line);
+			if (labels.containsKey(label)) {
+				throw new SyntaxError(srcLineNumber, String.format("Label \"%s\" already definied in line %d.", label, labels.get(label)));
+			}
+			labels.put(label, lineNumber);
+		} else {
+			Mnemonic mnemonic = getMnemonic(line);
+			if (mnemonic != null) {
+				lineNumber++;
+				mnemonics.add(mnemonic);
+			}
+		}
+	}
 
-  private static void showHelp() {
-    System.out.println("usage SPSAssembler <sorucefile> [<destination>]");
-    System.exit(0);
-  }
+	private static Mnemonic getMnemonic(String line) throws SyntaxError {
+		String newLine = stripComments(line);
+		if (StringUtils.isNotEmpty(newLine)) {
+			Mnemonic mnemonic = MnemonicFactory.getMnemonic(newLine, srcLineNumber);
+			return mnemonic;
+		}
+		return null;
+	}
+
+	private static String stripComments(String line) {
+		if (line.indexOf("*/") >= 0) {
+			inBlockComment = false;
+			return null;
+		}
+		if (inBlockComment) {
+			return null;
+		}
+		if (line.indexOf(";") >= 0) {
+			line = line.substring(0, line.indexOf(";")).trim();
+			return line;
+		}
+		if (line.startsWith("/*")) {
+			inBlockComment = true;
+			return null;
+		}
+		return line.trim();
+	}
+
+	private static String getLabel(String line) {
+		line = stripComments(line);
+		return line;
+	}
+
+	private static void showHelp() {
+		System.out.println("usage SPSAssembler <sorucefile> [<destination>]");
+		System.exit(0);
+	}
 
 }