|  | @@ -8,6 +8,7 @@ import org.slf4j.LoggerFactory;
 | 
	
		
			
				|  |  |  import net.hkzlab.devices.PALSpecs;
 | 
	
		
			
				|  |  |  import net.hkzlab.dupal.dupalproto.DuPALProto;
 | 
	
		
			
				|  |  |  import net.hkzlab.palanalisys.MacroState;
 | 
	
		
			
				|  |  | +import net.hkzlab.palanalisys.StateLink;
 | 
	
		
			
				|  |  |  import net.hkzlab.palanalisys.SubState;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  public class DuPALAnalyzer {
 | 
	
	
		
			
				|  | @@ -98,7 +99,7 @@ public class DuPALAnalyzer {
 | 
	
		
			
				|  |  |          //logger.info("Output states at start: " + String.format("%02X", (pins & IOasOUT_Mask)));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          mstate_idx = routstate >> pspecs.getROUT_READMaskShift();
 | 
	
		
			
				|  |  | -        MacroState ms = new MacroState(buildMSTag(mstate_idx), mstate_idx, pspecs.getNumROUTPins(), pspecs.getNumINPins());
 | 
	
		
			
				|  |  | +        MacroState ms = new MacroState(buildTag(mstate_idx), mstate_idx, pspecs.getNumROUTPins(), pspecs.getNumINPins());
 | 
	
		
			
				|  |  |          
 | 
	
		
			
				|  |  |          mStates[mstate_idx] = ms; // Save it in our Array
 | 
	
		
			
				|  |  |          logger.info("Added " + ms + " at index " + mstate_idx);
 | 
	
	
		
			
				|  | @@ -109,19 +110,39 @@ public class DuPALAnalyzer {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      private boolean analyzeMacroState(MacroState ms) {
 | 
	
		
			
				|  |  |          if((ms.substates.length > 0) && (ms.substates[0] == null)) {
 | 
	
		
			
				|  |  | -            logger.info("Generating all possible substates for this macro state...");
 | 
	
		
			
				|  |  | +            logger.info("Generating all possible substates for macro state ["+ms+"]");
 | 
	
		
			
				|  |  |              genAllMSSubStates(ms);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          int idx_mask = buildInputMask();
 | 
	
		
			
				|  |  |          int links_counter = 0;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        logger.info("Now check if we have a link to follow...");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          // Check if we have a link to generate
 | 
	
		
			
				|  |  | -        for(int idx = 0; idx <= 0x387FE; idx+=2) {
 | 
	
		
			
				|  |  | +        int maxidx = pspecs.getIO_WRITEMask() | pspecs.getINMask();
 | 
	
		
			
				|  |  | +        for(int idx = 0; idx <= maxidx; idx+=2) {
 | 
	
		
			
				|  |  |              if((idx & idx_mask) != 0) continue; // Skip this run
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              if(ms.links[links_counter] == null) {
 | 
	
		
			
				|  |  | -                // TODO: Ok, build a link and move to the next macrostate
 | 
	
		
			
				|  |  | +                logger.info("Generating link at index " + links_counter);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                pulseClock(idx); // Enter the new state
 | 
	
		
			
				|  |  | +                int pins = readPINs();
 | 
	
		
			
				|  |  | +                int mstate_idx = (pins & pspecs.getROUT_READMask()) >> pspecs.getROUT_READMaskShift();
 | 
	
		
			
				|  |  | +                MacroState nms = mStates[mstate_idx];
 | 
	
		
			
				|  |  | +                SubState ss = null;
 | 
	
		
			
				|  |  | +                StateLink sl = null;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                if(nms == null) {
 | 
	
		
			
				|  |  | +                    nms = new MacroState(buildTag(mstate_idx), mstate_idx, pspecs.getNumROUTPins(), pspecs.getNumINPins());
 | 
	
		
			
				|  |  | +                    mStates[mstate_idx] = nms;
 | 
	
		
			
				|  |  | +                }
 | 
	
		
			
				|  |  | +                ss = generateSubState(nms, idx, idx_mask);
 | 
	
		
			
				|  |  | +                sl = new StateLink(ms.tag, writeAddrToBooleans(idx, idx_mask), ss);
 | 
	
		
			
				|  |  | +                ms.links[links_counter] = sl;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                logger.info("Connected MS '"+ms+"' with SS '"+ss+"' ["+nms+"] with link '"+sl+"'");
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                  return true;
 | 
	
		
			
				|  |  |              }
 | 
	
	
		
			
				|  | @@ -136,61 +157,76 @@ public class DuPALAnalyzer {
 | 
	
		
			
				|  |  |          return (pspecs.getROUT_WRITEMask() | pspecs.getOEPinMask() | pspecs.getCLKPinMask() | (IOasOUT_Mask << 10));
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    private void genAllMSSubStates(MacroState ms) {
 | 
	
		
			
				|  |  | -        int idx_mask = buildInputMask();
 | 
	
		
			
				|  |  | -        int pins_1, pins_2, hiz_pins;
 | 
	
		
			
				|  |  | +    private boolean[] writeAddrToBooleans(int addr, int mask) {
 | 
	
		
			
				|  |  | +        ArrayList<Boolean> instate = new ArrayList<>();
 | 
	
		
			
				|  |  | +        for(int pin_idx = 0; pin_idx < 18; pin_idx++) {
 | 
	
		
			
				|  |  | +           if(((mask >> pin_idx) & 0x01) > 0) continue; // Output pin, not interested
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        logger.debug("Input mask " + Integer.toBinaryString(idx_mask) + "b");
 | 
	
		
			
				|  |  | +           if(((addr >> pin_idx) & 0x01) > 0) instate.add(true);
 | 
	
		
			
				|  |  | +           else instate.add(false);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        ArrayList<Byte> pinstate = new ArrayList<>();
 | 
	
		
			
				|  |  | -        ArrayList<Boolean> instate = new ArrayList<>();
 | 
	
		
			
				|  |  | +        boolean[] barr = new boolean[instate.size()];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        for(int idx = 0; idx <= 0x387FE; idx+=2) {
 | 
	
		
			
				|  |  | -            if((idx & idx_mask) != 0) continue; // Skip this run
 | 
	
		
			
				|  |  | +        for(int idx = 0; idx < barr.length; idx++) barr[idx] = instate.get(idx);
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        return barr;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            logger.debug("Testing combination 0x" + Integer.toHexString(idx));
 | 
	
		
			
				|  |  | +    private SubState generateSubState(MacroState ms, int idx, int idx_mask) {
 | 
	
		
			
				|  |  | +        SubState ss = null;
 | 
	
		
			
				|  |  | +        int pins_1, pins_2, hiz_pins;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            pinstate.clear();
 | 
	
		
			
				|  |  | -            instate.clear();
 | 
	
		
			
				|  |  | +        ArrayList<Byte> pinstate = new ArrayList<>();
 | 
	
		
			
				|  |  | +        boolean[] instate = null;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            writePINs(idx);
 | 
	
		
			
				|  |  | -            pins_1 = readPINs();
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -            writePINs(idx | IOasOUT_Mask);
 | 
	
		
			
				|  |  | -            pins_2 = readPINs();
 | 
	
		
			
				|  |  | +        writePINs(idx);
 | 
	
		
			
				|  |  | +        pins_1 = readPINs();
 | 
	
		
			
				|  |  | +           
 | 
	
		
			
				|  |  | +        writePINs(idx | (IOasOUT_Mask << 10));
 | 
	
		
			
				|  |  | +        pins_2 = readPINs();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            hiz_pins = (pins_1 ^ pins_2) & IOasOUT_Mask;
 | 
	
		
			
				|  |  | +        hiz_pins = (pins_1 ^ pins_2) & IOasOUT_Mask;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            for(int pin_idx = 0; pin_idx < 8; pin_idx++) {
 | 
	
		
			
				|  |  | -                if(((IOasOUT_Mask >> pin_idx) & 0x01) == 0) continue; // Not an output pin we're interested in
 | 
	
		
			
				|  |  | +        for(int pin_idx = 0; pin_idx < 8; pin_idx++) {
 | 
	
		
			
				|  |  | +            if(((IOasOUT_Mask >> pin_idx) & 0x01) == 0) continue; // Not an output pin we're interested in
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if(((hiz_pins >> pin_idx) & 0x01) > 0) pinstate.add((byte)-1);
 | 
	
		
			
				|  |  | -                else if (((pins_1 >> pin_idx) & 0x01) > 0) pinstate.add((byte)1);
 | 
	
		
			
				|  |  | -                else pinstate.add((byte)0);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | +            if(((hiz_pins >> pin_idx) & 0x01) > 0) pinstate.add((byte)-1);
 | 
	
		
			
				|  |  | +            else if (((pins_1 >> pin_idx) & 0x01) > 0) pinstate.add((byte)1);
 | 
	
		
			
				|  |  | +            else pinstate.add((byte)0);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            for(int pin_idx = 0; pin_idx < 18; pin_idx++) {
 | 
	
		
			
				|  |  | -                if(((idx_mask >> pin_idx) & 0x01) > 0) continue; // Output pin, not interested
 | 
	
		
			
				|  |  | +        instate = writeAddrToBooleans(idx, idx_mask);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -                if(((idx >> pin_idx) & 0x01) > 0) instate.add(true);
 | 
	
		
			
				|  |  | -                else instate.add(false);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            
 | 
	
		
			
				|  |  | -            logger.debug("pinstate len: " + pinstate.size() + " instate len: " + instate.size());
 | 
	
		
			
				|  |  | +        logger.debug("pinstate len: " + pinstate.size() + " instate len: " + instate.length);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            Byte[] out_state = pinstate.toArray(new Byte[pinstate.size()]);
 | 
	
		
			
				|  |  | -            int ss_idx = SubState.calculateSubStateIndex(instate.toArray(new Boolean[instate.size()]));
 | 
	
		
			
				|  |  | -            int ss_key = SubState.calculateSubStateKey(out_state);
 | 
	
		
			
				|  |  | -            SubState ss = null;
 | 
	
		
			
				|  |  | +        Byte[] out_state = pinstate.toArray(new Byte[pinstate.size()]);
 | 
	
		
			
				|  |  | +        int ss_idx = SubState.calculateSubStateIndex(instate);
 | 
	
		
			
				|  |  | +        int ss_key = SubState.calculateSubStateKey(out_state);
 | 
	
		
			
				|  |  |              
 | 
	
		
			
				|  |  | -            logger.debug("substate index: " + ss_idx + " key: " + ss_key);
 | 
	
		
			
				|  |  | +        logger.debug("substate index: " + ss_idx + " key: " + ss_key);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            ss = ms.ssMap.get(Integer.valueOf(ss_key));
 | 
	
		
			
				|  |  | -            if(ss == null) {
 | 
	
		
			
				|  |  | -                ss = new SubState(ms.tag, ms, out_state);
 | 
	
		
			
				|  |  | -                ms.ssMap.put(Integer.valueOf(ss_key), ss);
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            ms.substates[ss_idx] = ss;
 | 
	
		
			
				|  |  | +        ss = ms.ssMap.get(Integer.valueOf(ss_key));
 | 
	
		
			
				|  |  | +        if(ss == null) {
 | 
	
		
			
				|  |  | +            ss = new SubState(ms.tag, ms, out_state);
 | 
	
		
			
				|  |  | +            ms.ssMap.put(Integer.valueOf(ss_key), ss);
 | 
	
		
			
				|  |  | +        } 
 | 
	
		
			
				|  |  | +        
 | 
	
		
			
				|  |  | +        ms.substates[ss_idx] = ss;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        return ss;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    private void genAllMSSubStates(MacroState ms) {
 | 
	
		
			
				|  |  | +        int idx_mask = buildInputMask();
 | 
	
		
			
				|  |  | +        logger.debug("Input mask " + Integer.toBinaryString(idx_mask) + "b");
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        int maxidx = pspecs.getIO_WRITEMask() | pspecs.getINMask();
 | 
	
		
			
				|  |  | +        for(int idx = 0; idx <= maxidx; idx+=2) {
 | 
	
		
			
				|  |  | +            if((idx & idx_mask) != 0) continue; // Skip this run
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +            logger.debug("Testing combination 0x" + Integer.toHexString(idx));
 | 
	
		
			
				|  |  | +            generateSubState(ms, idx, idx_mask);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          writePINs(0);
 | 
	
	
		
			
				|  | @@ -206,7 +242,7 @@ public class DuPALAnalyzer {
 | 
	
		
			
				|  |  |          return DuPALProto.handleWRITEResponse(dpm.readResponse());
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    static private String buildMSTag(int idx) {
 | 
	
		
			
				|  |  | +    static private String buildTag(int idx) {
 | 
	
		
			
				|  |  |          return "TAG_"+Integer.toHexString(idx);
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |