|  | @@ -44,15 +44,18 @@ import org.reflections.util.ClasspathHelper;
 | 
	
		
			
				|  |  |  import org.reflections.util.ConfigurationBuilder;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.annotations.SPSOutputter;
 | 
	
		
			
				|  |  | +import de.mcs.tools.sps.exceptions.HardwareException;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.exceptions.IllegalArgument;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.exceptions.SyntaxError;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.CALL;
 | 
	
		
			
				|  |  | +import de.mcs.tools.sps.mnemonic.DFSB;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.HARDWARE;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.JMP;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.LOOPC;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.LOOPD;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.Mnemonic;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.MnemonicFactory;
 | 
	
		
			
				|  |  | +import de.mcs.tools.sps.mnemonic.NOP;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.PAGE;
 | 
	
		
			
				|  |  |  import de.mcs.tools.sps.mnemonic.RJMP;
 | 
	
		
			
				|  |  |  import de.mcs.utils.jsap.Command;
 | 
	
	
		
			
				|  | @@ -77,6 +80,8 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |    private static File destinationFile;
 | 
	
		
			
				|  |  |    private static String outputFormat;
 | 
	
		
			
				|  |  |    private static File includes;
 | 
	
		
			
				|  |  | +  private static Outputter outputter;
 | 
	
		
			
				|  |  | +  private static String destinationStr;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    private int lineNumber;
 | 
	
		
			
				|  |  |    // private int srcLineNumber;
 | 
	
	
		
			
				|  | @@ -86,7 +91,6 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |    private boolean inMacro;
 | 
	
		
			
				|  |  |    private Macro actualMacro;
 | 
	
		
			
				|  |  |    private Map<String, Macro> macros;
 | 
	
		
			
				|  |  | -  private static Outputter outputter;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    @SwitchOption(shortKey = 'h', longKey = "help", name = "help", help = "show this help page", required = false, defaultValue = false)
 | 
	
		
			
				|  |  |    public static void doHelp(boolean value) {
 | 
	
	
		
			
				|  | @@ -103,7 +107,7 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    @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()));
 | 
	
		
			
				|  |  | +    destinationStr = value;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    @FileOption(shortKey = 'i', longKey = "includes", name = "includes", defaultValue = "", help = "where to find the includes files.", required = false)
 | 
	
	
		
			
				|  | @@ -137,6 +141,12 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        CommandlineProcessor.processCommandline(SPSAssembler.class, args);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        destination = HARDWARE.valueOf((destinationStr.toUpperCase()));
 | 
	
		
			
				|  |  | +      } catch (IllegalArgumentException e) {
 | 
	
		
			
				|  |  | +        throw new HardwareException(String.format("Hardware %s unknow for this assembler", destinationStr));
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        registerAllOutputter();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        if ((source == null) || (!source.exists())) {
 | 
	
	
		
			
				|  | @@ -155,6 +165,10 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |        System.out.printf("source file: %s \r\n", source.getName());
 | 
	
		
			
				|  |  |        System.out.printf("destination file: %s \r\n", destinationFile.getName());
 | 
	
		
			
				|  |  |        System.out.printf("output format: %s \r\n", outputFormat);
 | 
	
		
			
				|  |  | +      System.out.printf("hardware: %s \r\n", destination.name());
 | 
	
		
			
				|  |  | +      if (includes != null) {
 | 
	
		
			
				|  |  | +        System.out.printf("includes foldes: %s \r\n", includes.getCanonicalPath());
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |        System.out.println();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        try {
 | 
	
	
		
			
				|  | @@ -278,6 +292,8 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    private void doWork(File source) throws IOException, SyntaxError {
 | 
	
		
			
				|  |  | +    System.out.printf("start parsing file: %s\r\n", source.getName());
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      List<String> sourceFile = Files.readAllLines(source.toPath(), Charset.forName("UTF-8"));
 | 
	
		
			
				|  |  |      for (int i = 0; i < sourceFile.size(); i++) {
 | 
	
		
			
				|  |  |        String line = sourceFile.get(i);
 | 
	
	
		
			
				|  | @@ -297,7 +313,58 @@ public class SPSAssembler {
 | 
	
		
			
				|  |  |      // Checking destination
 | 
	
		
			
				|  |  |      checkingHardware();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    System.out.printf("start parsing file: %s\r\n", source.getName());
 | 
	
		
			
				|  |  | +    calculatingJumps();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    paddingSubroutines();
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // checking size of program
 | 
	
		
			
				|  |  | +    checkingProgramSize();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private void paddingSubroutines() throws SyntaxError {
 | 
	
		
			
				|  |  | +    // checking location of Subroutines
 | 
	
		
			
				|  |  | +    if (destination.equals(HARDWARE.ARDUINOSPS) || destination.equals(HARDWARE.TINYSPS)) {
 | 
	
		
			
				|  |  | +      int position = 0;
 | 
	
		
			
				|  |  | +      for (int i = 0; i < mnemonics.size(); i++) {
 | 
	
		
			
				|  |  | +        Mnemonic mnemonic = mnemonics.get(i);
 | 
	
		
			
				|  |  | +        if (mnemonic instanceof DFSB) {
 | 
	
		
			
				|  |  | +          break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +        position++;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      if (position < 256) {
 | 
	
		
			
				|  |  | +        int count = 256 - position;
 | 
	
		
			
				|  |  | +        for (int i = 0; i < count; i++) {
 | 
	
		
			
				|  |  | +          mnemonics.add(position, new NOP(""));
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private void checkingProgramSize() throws HardwareException {
 | 
	
		
			
				|  |  | +    int prgSize = 0;
 | 
	
		
			
				|  |  | +    for (Mnemonic mnemonic : mnemonics) {
 | 
	
		
			
				|  |  | +      if (mnemonic instanceof DFSB) {
 | 
	
		
			
				|  |  | +        break;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      prgSize++;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    int maxSize = 128;
 | 
	
		
			
				|  |  | +    switch (destination) {
 | 
	
		
			
				|  |  | +    case ARDUINOSPS:
 | 
	
		
			
				|  |  | +    case TINYSPS:
 | 
	
		
			
				|  |  | +      maxSize = 256;
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    default:
 | 
	
		
			
				|  |  | +      break;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    if (prgSize > maxSize) {
 | 
	
		
			
				|  |  | +      throw new HardwareException(
 | 
	
		
			
				|  |  | +          String.format("Program exceeding size (%d) for hardeware %s (%d).", prgSize, destination, maxSize));
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  private void calculatingJumps() throws SyntaxError {
 | 
	
		
			
				|  |  |      int address = 0;
 | 
	
		
			
				|  |  |      Mnemonic predecessor = null;
 | 
	
		
			
				|  |  |      for (Iterator<Mnemonic> iterator = mnemonics.iterator(); iterator.hasNext();) {
 |