浏览代码

Cleanup, begin building the new pal specs

Fabio Battaglia 5 年之前
父节点
当前提交
135d0df62a

+ 1 - 2
src/main/java/info/hkzlab/dupal/analyzer/App.java

@@ -8,8 +8,7 @@ import info.hkzlab.dupal.analyzer.board.boardio.*;
 import info.hkzlab.dupal.analyzer.devices.*;
 
 public class App {
-    public static volatile String[] palTypes = { PAL10L8Specs.PAL_TYPE, PAL12L6Specs.PAL_TYPE, PAL16L8Specs.PAL_TYPE, 
-                                                PAL16R4Specs.PAL_TYPE, PAL16R6Specs.PAL_TYPE, PAL16R8Specs.PAL_TYPE };
+    public static volatile String[] palTypes = { PAL16L8Specs.PAL_TYPE };
 
     private final static Logger logger = LoggerFactory.getLogger(DuPALManager.class);
 

+ 0 - 747
src/main/java/info/hkzlab/dupal/analyzer/board/boardio/DuPALAnalyzer.java

@@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
 import info.hkzlab.dupal.analyzer.board.dupalproto.DuPALProto;
 import info.hkzlab.dupal.analyzer.devices.*;
 import info.hkzlab.dupal.analyzer.exceptions.*;
-import info.hkzlab.dupal.analyzer.palanalisys.*;
 
 public class DuPALAnalyzer {
     private static final Logger logger = LoggerFactory.getLogger(DuPALAnalyzer.class);
@@ -31,13 +30,8 @@ public class DuPALAnalyzer {
     private static final String OUT_TABLE = "dupal_thrtable.tbl";
     private static final String DUPAL_STRUCT = "dupal_struct.txt";
 
-    private static final long SAVE_INTERVAL = 5 * 60 * 1000; // 5 minutes
-
-    private StatesContainer psContainer; 
-
     private final DuPALManager dpm;
     private final PALSpecs pspecs;
-    private final HashMap<Integer, StateLink[]> pathMap;
     
     private final String serdump_path;
     private final String tblPath;
@@ -46,7 +40,6 @@ public class DuPALAnalyzer {
     private int IOasOUT_Mask = -1;
     private int additionalOUTs = 0;
 
-    private int lastUnexploredMS_idx = -1;
 
     public DuPALAnalyzer(final DuPALManager dpm, final PALSpecs pspecs, final int IOasOUT_Mask, final String outPath) {
         this.dpm = dpm;
@@ -56,752 +49,12 @@ public class DuPALAnalyzer {
         serdump_path = outPath + File.separator+ SERIALIZED_DUMP;
         tblPath = outPath + File.separator + OUT_TABLE;
         structPath = outPath + File.separator + DUPAL_STRUCT;
-
-        this.pathMap = new HashMap<>();
-        
-
-        if(outPath != null) psContainer = restoreStatus(serdump_path, pspecs);
-
-        if (psContainer == null) {
-            // Create a container with space for 2^X MacroStates, where X is the number of registered outputs
-            this.psContainer = new StatesContainer((1 << pspecs.getNumROUTPins()), pspecs.toString());
-            logger.info("Provisioning for " +psContainer.mStates.length+" possible MacroStates");
-        } else {
-            logger.info("State was restored from previous serialized dump. PAL Model: " + psContainer.palName);
-        }
     } 
     
     public DuPALAnalyzer(final DuPALManager dpm, final PALSpecs pspecs) {
         this(dpm, pspecs, -1, null);
     }
 
-    public void saveStatus(final String path) {
-        try {
-            FileOutputStream fileOut = new FileOutputStream(path);
-            ObjectOutputStream out = new ObjectOutputStream(fileOut);
-        
-            out.writeObject(psContainer);
-            out.close();
-            fileOut.close();
-
-            logger.info("Saved state to " + path);
-        } catch (IOException e) {
-            logger.warn("Unable to save status to " + path);
-            e.printStackTrace();
-        }
-    }
-
-    public StatesContainer restoreStatus(final String path, final PALSpecs specs) {
-        try {
-            FileInputStream fileIn = new FileInputStream(path);
-            ObjectInputStream in = new ObjectInputStream(fileIn);
-        
-            StatesContainer psc = (StatesContainer)in.readObject();
-            in.close();
-            fileIn.close();
-
-            if(!psc.palName.equals(specs.toString())) {
-                logger.error("The state that was restored was dumped from a different type of PAL ("+psc.palName+"). Ignoring.");
-
-                return null;
-            } else {
-                logger.info("Restored state from " + path);
-
-                return psc;
-            }
-        } catch (ClassNotFoundException e) {
-            e.printStackTrace();
-        } catch (FileNotFoundException e) {
-            logger.warn("Could not find " + path);
-        } catch (IOException e) {
-            logger.warn("Unable to save status to " + path);
-            e.printStackTrace();
-        }
-
-        return null;
-    }
-
     public void startAnalisys() throws InvalidIOPinStateException, ICStateException, DuPALBoardException {
-        logger.info("Device:" + pspecs + " known IOs? " + (IOasOUT_Mask >= 0 ? "Y" : "N"));
-
-        if(IOasOUT_Mask < 0) { // We need to detect the status of the IOs...
-            IOasOUT_Mask = guessIOs(); // Try to guess whether IOs are Inputs or Outputs
-        }
-
-        // Given the mask that we have recovered before, find how many additional outputs we have in this PAL
-        additionalOUTs = countHIBits(IOasOUT_Mask);
-
-        internal_analisys();
-        if(serdump_path != null) saveStatus(serdump_path);
-
-        printUnvisitedMacroStates(psContainer.mStates);
-        printAnalisysOutput();
-    }
-
-    private void printAnalisysOutput() {
-        FileOutputStream fout = null;
-        
-        try {
-            fout = new FileOutputStream(structPath);
-            printStateStructure(fout, pspecs, psContainer.mStates);
-            fout.close();
-        } catch(IOException e) {
-            logger.error("Error printing out the analisys struct.");
-            e.printStackTrace();           
-        }
-        try {
-            fout = new FileOutputStream(tblPath);
-            printLogicTable(fout, pspecs, IOasOUT_Mask, psContainer.mStates);
-            fout.close();
-        } catch(IOException e) {
-            logger.error("Error printing out the registered outputs table (not including outputs).");
-            e.printStackTrace();
-        }
-    }
-
-    private int guessIOs() throws DuPALBoardException {
-        logger.info("starting...");
-
-        int inmask = pspecs.getINMask() | pspecs.getIO_WRITEMask(); // Get a mask for writing the INputs and the IOs (which could be inputs)
-
-        logger.info("inmask: " + Integer.toHexString(inmask));
-
-        /* We'll try toggling all inputs combinations in the current state,
-         * Then we'll toggle the clock to try to move to another state, this for all the input combinations, again
-         * 
-         * We won't cover all the possible states, but we're just trying to guess which pins are output here.
-         */
-
-        int read, out_pins = 0;
-        for(int idx = 0; idx <= inmask; idx++) { // Try all input combinations
-            if((idx & ~inmask) != 0) continue; // We're trying to set a pin that is neither an input nor an IO
-
-            if(out_pins == pspecs.getIO_READMask()) break; // Apparently we found that all the IOs are outputs...
-
-            logger.info("run " + Integer.toHexString(idx >> 1) + " | inmask: 0x"+String.format("%06X", inmask)+" guessed outs: 0x" + String.format("%02X", out_pins) + " / " + Integer.toBinaryString(out_pins)+"b");
-
-            int new_inmask, write_addr;
-            for(int i_idx = 0; i_idx <= inmask; i_idx++) { // Now, try all the input combinations for this state
-                if((i_idx & ~inmask) != 0) continue; // We need to skip this round
-                if(out_pins == pspecs.getIO_READMask()) break; // Stop checking, we already found that all IOs are outputs...
-                
-                write_addr = i_idx & ~(pspecs.getOEPinMask() | pspecs.getCLKPinMask());
-                writePINs(write_addr);
-                read = readPINs();
-                out_pins |= (read ^ (write_addr >>  PALSpecs.READ_WRITE_SHIFT)) & pspecs.getIO_READMask();
-               
-                // Check if we need to update the input mask
-                new_inmask = inmask & ~(out_pins << PALSpecs.READ_WRITE_SHIFT);
-                if(new_inmask != inmask) {
-                    inmask = new_inmask;
-                    logger.info("Updated input mask, now -> " + String.format("%06X", inmask) + " outs: " + String.format("%02X", out_pins));
-                }
-                    
-                logger.debug("internal loop: " + Integer.toBinaryString(i_idx) + " outs:" + String.format("%02X", out_pins));
-            }
-
-
-            if(pspecs.getCLKPinMask() == 0) break; // We have lo CLK pin, nothing to pulse, no need to try multiple states
-
-            // pulse the clock to try and move to a random new state
-            pulseClock(idx & ~pspecs.getOEPinMask());
-        }
-
-        logger.info("end... I guessed: 0x" + Integer.toHexString(out_pins) + " / " + Integer.toBinaryString(out_pins)+"b");
-
-        return out_pins;
-    }
-
-    private void pulseClock(int addr) throws DuPALBoardException {
-        int addr_clk = (addr | pspecs.getCLKPinMask()) & ~pspecs.getOEPinMask();
-        int addr_noclk = addr & ~(pspecs.getOEPinMask() | pspecs.getCLKPinMask());
-        logger.debug("Pulsing clock with addr: " + Integer.toHexString(addr_clk) + " | " + Integer.toHexString(addr_noclk));
-        
-        try {
-            writePINs(addr_noclk); // Set the address, but keep CLK pin low
-            writePINs(addr_clk); // Set CLK pin high..
-            writePINs(addr_noclk); // CLK pin low again
-        } catch(DuPALBoardException e) {
-            logger.error("Pulsing clock to get to address " + Integer.toHexString(addr_noclk) + " failed.");
-            throw e;
-        }
-    }
-
-    private void internal_analisys() throws InvalidIOPinStateException, ICStateException, DuPALBoardException {
-        logger.info("Device: " + pspecs + " Outs: " + Integer.toBinaryString(IOasOUT_Mask | pspecs.getOUT_READMask())+"b");
-        int pins, mstate_idx;
-
-        writePINs(0x00); // Set the pins to to 0, this would leave the /OE pin and clock to low
-        pins = readPINs();
-
-        int rout_state = pins & pspecs.getROUT_READMask();
-        if(pspecs.getNumROUTPins() > 0) logger.info("Registered outputs at start: " + String.format("%02X", rout_state));
-
-        mstate_idx = rout_state >> pspecs.getROUT_READMaskShift();
-        MacroState ms = null, nms = null;
-        
-        if(psContainer.mStates[mstate_idx] == null) {
-            ms = new MacroState(buildTag(mstate_idx), mstate_idx, pspecs.getNumROUTPins(), (pspecs.getNumINPins()  + (pspecs.getNumIOPins() - additionalOUTs)));
-            psContainer.mStates[mstate_idx] = ms;
-            logger.info("Added MacroState [" + ms + "] at index " + mstate_idx);
-        } else {
-            ms = psContainer.mStates[mstate_idx];
-            logger.info("Recovered MacroState ["+ms+"] from index " + mstate_idx);
-        }
-
-        long last_save = 0;
-        while(true) {
-            long now = System.currentTimeMillis();
-            if(((now - last_save) >= SAVE_INTERVAL) && (serdump_path != null)) {
-                saveStatus(serdump_path);
-                last_save = now;
-            }
-
-            if(ms == null) {
-                logger.info("There are no more unknown StateLinks we can reach.");
-                return;
-            }
-
-            nms = analyzeMacroState(ms);
-            
-            if(nms != null) {
-                logger.debug("We moved to MacroState ["+nms+"]");
-                ms = nms;
-                nms = null;
-            } else {
-                logger.info("No more StateLinks to generate in ["+ms+"]");
-
-                StateLink[] slPath = findPathToNewStateLinks(ms);
-                
-                if(slPath == null) {
-                    logger.info("Found no paths starting from ["+ms+"]");
-                    ms = null;
-                } else {
-                    int old_rpin_status, cur_rpin_status;
-
-                    old_rpin_status = ((readPINs() & pspecs.getROUT_READMask()) >> pspecs.getROUT_READMaskShift());
-                    ms = slPath[slPath.length - 1].destMS; // Mark the new macro state
-                    
-                    logger.info("Found a path to another MacroState: ["+ms+"]");
-                    // Traverse the path
-                    for(StateLink sl : slPath) {
-                        logger.trace("Traversing SL -> " + sl);
-                        pulseClock(sl.raw_addr);
-                    }
-
-                    // Check that we got to the right state
-                    cur_rpin_status = ((readPINs() & pspecs.getROUT_READMask()) >> pspecs.getROUT_READMaskShift());
-                    if(cur_rpin_status != ms.rpin_status) {
-                        logger.error("Mismatch between the current reg. out state ("+String.format("%02X", cur_rpin_status)+") and expected state ("+String.format("%02X", ms.rpin_status)+"), old reg. out state was " + String.format("%02X", old_rpin_status));
-                        throw new ICStateException("Unexpected registered out state after traversing a state link path.");
-                    }
-                }
-            }
-        }
-    }
-
-    private int slPathGetHash(MacroState sms, MacroState dms) {
-        return ((sms.rpin_status * 31) + dms.rpin_status);
-    }
-
-    private StateLink[] findPathToNewStateLinks(MacroState start_ms) {
-        int precalc_idx = 0;
-
-        if((lastUnexploredMS_idx >= 0) && (psContainer.mStates[lastUnexploredMS_idx].link_count < start_ms.links.length)) {
-            int pathHash = slPathGetHash(start_ms, psContainer.mStates[lastUnexploredMS_idx]);
-            if(pathMap.containsKey(pathHash)) { 
-                logger.info("Trying to reach MacroState " + String.format("%02X", lastUnexploredMS_idx) + ": it has " + psContainer.mStates[lastUnexploredMS_idx].link_count + " links.");
-                precalc_idx = lastUnexploredMS_idx;
-            }
-        }
-
-        // Search for a state that still has unexplored links
-        for(int ms_idx = precalc_idx; ms_idx < psContainer.mStates.length; ms_idx++) {
-            if((psContainer.mStates[ms_idx] != null) && (psContainer.mStates[ms_idx] != start_ms)) {
-                if(psContainer.mStates[ms_idx].link_count < psContainer.mStates[ms_idx].links.length) {
-                        logger.info("Found unexplored link in ["+psContainer.mStates[ms_idx]+"]");
-
-                        lastUnexploredMS_idx = ms_idx; // Save it for faster search later
-
-                        int path_hash = slPathGetHash(start_ms, psContainer.mStates[ms_idx]);
-                        StateLink[] sll = pathMap.get(Integer.valueOf(path_hash));
-
-                        if(sll != null) {
-                            if(sll[sll.length-1].destMS != psContainer.mStates[ms_idx]) {
-                                logger.warn("Got an hash collision trying to reach ["+psContainer.mStates[ms_idx]+"] from ["+start_ms+"]");
-                                lastUnexploredMS_idx = -1;
-                                sll = null;
-                            }
-                        }
-
-                        if(sll == null) {
-                            sll = internal_searchBestPath(start_ms, psContainer.mStates[ms_idx]);
-                            if (sll != null) pathMap.put(Integer.valueOf(path_hash), sll);
-                        }
-
-                        if(sll != null) return sll; // Ok, we found a path
-                }
-            }
-        }
-
-        return null; // Finding nothing
-    }
-
-    private Map<MacroState, Integer> internal_calculateCostMap(MacroState[] states, MacroState destState) {
-        HashMap<MacroState, Integer> costMap = new HashMap<>();
-        Set<MacroState> msToSearch = new HashSet<>();
-
-        Set<MacroState> searchAdd = new HashSet<>();
-        Set<MacroState> searchDel = new HashSet<>();
-        searchAdd.add(destState);
-
-        costMap.put(destState, 0);
-
-        while(searchAdd.size() > 0) {
-            msToSearch.clear();
-            msToSearch.addAll(searchAdd);
-
-            searchAdd.clear();
-            searchDel.clear();
-
-            // Loop through all the states
-            for(int msIdx = 0; msIdx < states.length; msIdx++) {
-                if((states[msIdx] == null) || msToSearch.contains(states[msIdx])) continue;
-
-                // Loop through all the kinks for this state
-                for(int linkIdx = 0; linkIdx < states[msIdx].links.length; linkIdx++) {
-                    if(states[msIdx].links[linkIdx] == null) continue; // This link was not created, skip
-                    
-                    if(msToSearch.contains(states[msIdx].links[linkIdx].destMS)) { // The destination is between the MacroStates we're searching
-                        if(!costMap.containsKey(states[msIdx])) searchAdd.add(states[msIdx]); // If cost was not calculated for this one
-                        else { // Cost already calculated. Check if we need to update it
-                            int newCost = costMap.get(states[msIdx].links[linkIdx].destMS) + 1;
-                            int oldCost = costMap.get(states[msIdx]);
-                            if(oldCost > newCost) {
-                                costMap.put(states[msIdx], newCost);
-                                logger.trace("Cost updated from " + oldCost + " to " + newCost + " to reach " + states[msIdx]);
-                            }
-                        }
-
-                        if(states[msIdx].links[linkIdx].destMS == destState) costMap.put(states[msIdx], 1);
-                        else {
-                            int cost = costMap.get(states[msIdx].links[linkIdx].destMS) + 1;
-                            if(!costMap.containsKey(states[msIdx]) || (costMap.get(states[msIdx]) > cost)) costMap.put(states[msIdx], cost);
-                        }
-                    }
-                }
-            }
-        }
-        
-
-        return costMap;
-    }
-
-    private StateLink[] internal_searchBestPath(MacroState start, MacroState dest) {
-        logger.info("Searching for best path from ["+start+"] to ["+dest+"]");
-
-        Stack<StateLink> slStack = new Stack<>();
-        MacroState curMS = start, nextMS;
-        StateLink nextSL;
-
-        Map<MacroState, Integer> costMap = internal_calculateCostMap(psContainer.mStates, dest);
-        
-        boolean foundLink = false;
-        int cost = -1;
-        while(curMS != null) {
-            nextMS = null;
-            nextSL = null;
-
-            if(curMS == dest) {
-                logger.trace("Arrived at " + dest);
-                foundLink = true;
-                break;
-            } 
-
-            for(int sl_idx = 0; sl_idx < curMS.links.length; sl_idx++) {
-                if(curMS.links[sl_idx] == null) continue;
-
-                MacroState dms = curMS.links[sl_idx].destMS;
-
-                if(costMap.containsKey(dms) && ((cost < 0) || costMap.get(dms) < cost)) {
-                    logger.trace("current cost " + cost + " dms:"+dms+" cost:"+costMap.get(dms));
-                    cost = costMap.get(dms);
-                    nextMS = curMS.links[sl_idx].destMS;
-                    nextSL = curMS.links[sl_idx];
-                }
-            }
-
-            curMS = nextMS;
-            if(nextSL != null) slStack.push(nextSL);
-        }
-
-        if(foundLink && slStack.size() > 0) {
-            logger.info("Path from ["+start+"] to ["+dest+"] found with cost " + slStack.size());
-            return slStack.toArray(new StateLink[slStack.size()]);
-        } 
-        else {
-            logger.info("No path found between ["+start+"] to ["+dest+"]");
-            return null;
-        } 
-    }
-    
-    private MacroState analyzeMacroState(MacroState ms) throws InvalidIOPinStateException, DuPALBoardException {
-        if(!ms.ss_ready) {
-            logger.info("Generating all ("+ms.substates.length+") possible SubStates for MacroState ["+ms+"]");
-            genAllMSSubStates(ms);
-        } else {
-            logger.debug("SubStates already generated for MacroStates ["+ms+"]");
-        }
-
-        int idx_mask = buildInputMask();
-
-        if(pspecs.getNumROUTPins() == 0) return null; // We have no registered outputs, no need to check for other MacroStates
-
-        logger.debug("Now check if we have a new StateLink to try...");
-        if(ms.link_count == ms.links.length) return null;
-
-        // Check if we have a link to generate
-        int links_counter;
-        int maxidx = pspecs.getIO_WRITEMask() | pspecs.getINMask();
-        while (ms.last_link_idx <= maxidx) { // Search for the next valid address
-            if((ms.last_link_idx & idx_mask) != 0) { ms.last_link_idx +=2; continue; } // Skip this run
-            links_counter = ms.link_count;
-
-            logger.debug("Generating StateLink at index " + links_counter);
-
-            pulseClock(ms.last_link_idx); // Enter the new state
-            int pins = readPINs();
-            int mstate_idx = (pins & pspecs.getROUT_READMask()) >> pspecs.getROUT_READMaskShift();
-            MacroState nms = psContainer.mStates[mstate_idx];
-            StateLink sl = null;
-
-            if(nms == null) {
-                nms = new MacroState(buildTag(mstate_idx), mstate_idx, pspecs.getNumROUTPins(), (pspecs.getNumINPins() + (pspecs.getNumIOPins() - additionalOUTs)));
-                psContainer.mStates[mstate_idx] = nms;
-            }
-            sl = new StateLink(ms.tag, ms.last_link_idx, nms);
-            ms.links[links_counter] = sl;
-            ms.link_count++;
-
-            logger.info("Connected MS '"+ms+"' with MS '"+nms+"' by SL '"+sl+"' ("+links_counter+"/"+ms.links.length+")");
-
-            ms.last_link_idx += 2;
-
-            return nms;
-        }
-
-        return null; // We did not move from the macrostate
-    }
-
-    /* 
-     * Simply count how many bits set to high we have in the mask
-     */
-    static private int countHIBits(int mask) {
-        int count = 0;
-
-        for(int idx = 0; idx < 32; idx++) count += ((mask >> idx) & 0x01);
-
-        return count;
-    }
-
-    private int buildInputMask() {
-        return (pspecs.getROUT_WRITEMask() | pspecs.getOEPinMask() | pspecs.getCLKPinMask() | pspecs.getOUT_WRITEMask() | (IOasOUT_Mask << PALSpecs.READ_WRITE_SHIFT));
-    }
-
-    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
-
-           if(((addr >> pin_idx) & 0x01) > 0) instate.add(true);
-           else instate.add(false);
-        }
-
-        boolean[] barr = new boolean[instate.size()];
-
-        for(int idx = 0; idx < barr.length; idx++) barr[idx] = instate.get(idx);
-        
-        return barr;
-    }
-
-    private SubState generateSubState(MacroState ms, int idx, int idx_mask) throws InvalidIOPinStateException,
-            DuPALBoardException {
-        SubState ss = null;
-        int pins_1 = 0, pins_2 = 0, hiz_pins = 0;
-
-        ArrayList<Byte> iout_state = new ArrayList<>();
-        ArrayList<Byte> out_state = new ArrayList<>();
-        boolean[] instate = null;
-
-        if((IOasOUT_Mask != 0) || (pspecs.getNumOUTPins() > 0)) { // Check that we have output ports to actually scan
-            writePINs(idx); // Write the address to the inputs, attempt to force the current outputs to 0
-            pins_1 = readPINs(); // And read back
-            
-            // Check that inputs really are inputs,
-            // We'd expect that what we wrote to the IO pins that we consider inputs is not forced to a different level,
-            // E.g. if we write an address that contains a high level into an input and we detect a low level, it means that what
-            // we considered as an input, is actually behaving as an output. We probably did not detect them correctly.
-            if((pins_1 & (pspecs.getIO_READMask() & ~IOasOUT_Mask)) != ((idx >> PALSpecs.READ_WRITE_SHIFT) & (pspecs.getIO_READMask() & ~IOasOUT_Mask))) {
-                int extraOut = (pins_1 & (pspecs.getIO_READMask() & ~IOasOUT_Mask)) ^ ((idx >> PALSpecs.READ_WRITE_SHIFT) & (pspecs.getIO_READMask() & ~IOasOUT_Mask));
-                logger.error("Detected an input that is acting as output when in MS ["+ms+"] -> expected outs: " + String.format("%02X", IOasOUT_Mask) + " actual outs: " + String.format("%02X", IOasOUT_Mask | extraOut));
-                throw new InvalidIOPinStateException("Invalid IO State detected. Expected outputs: " + String.format("%02X", IOasOUT_Mask) + " detected: " + String.format("%02X", IOasOUT_Mask | extraOut), IOasOUT_Mask, IOasOUT_Mask | extraOut);
-            }
-            
-            // Write the address to the inputs, this time try to force the outputs to 1
-            writePINs(idx | (IOasOUT_Mask << PALSpecs.READ_WRITE_SHIFT) | pspecs.getOUT_WRITEMask());
-            pins_2 = readPINs();
-
-            // Check if forcing the outputs has create a difference in the result:
-            // If a difference is detected, it means the pin is in high impedence state.
-            hiz_pins = (pins_1 ^ pins_2) & (IOasOUT_Mask | pspecs.getOUT_READMask());
-        }
-
-        // Build a list of the states for IO as outputs
-        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) iout_state.add((byte)-1);
-            else if (((pins_1 >> pin_idx) & 0x01) > 0) iout_state.add((byte)1);
-            else iout_state.add((byte)0);
-        }
-
-        // Build a list of the states for output pins
-        for(int pin_idx = 0; pin_idx < 8; pin_idx++) {
-            if(((pspecs.getOUT_READMask() >> pin_idx) & 0x01) == 0) continue; // Not an output pin we're interested in
-
-            if(((hiz_pins >> pin_idx) & 0x01) > 0) out_state.add((byte)-1);
-            else if (((pins_1 >> pin_idx) & 0x01) > 0) out_state.add((byte)1);
-            else out_state.add((byte)0);
-        }
-
-        instate = writeAddrToBooleans(idx, idx_mask);
-
-        logger.debug("iout_state len: " + iout_state.size() + " out_state len: " + out_state.size() + " instate len: " + instate.length);
-
-        Byte[] iout_state_arr = iout_state.toArray(new Byte[iout_state.size()]);
-        Byte[] out_state_arr = out_state.toArray(new Byte[out_state.size()]);
-
-        int ss_idx = SubState.calculateSubStateIndex(instate);
-        int ss_key = SubState.calculateHashFromArrays(new Byte[][] {iout_state_arr, out_state_arr});
-            
-        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, iout_state_arr, out_state_arr);
-            ms.ssMap.put(Integer.valueOf(ss_key), ss);
-        } else {
-            logger.debug("SubState index: " + ss_idx + " key: " +ss_key+ " was already present.");
-        }
-        
-        ms.substates[ss_idx] = ss;
-
-        return ss;
-    }
-
-    private void genAllMSSubStates(MacroState ms) throws InvalidIOPinStateException, DuPALBoardException {
-        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++) {
-            if((idx & idx_mask) != 0) continue; // Skip this run
-
-            generateSubState(ms, idx, idx_mask);
-        }
-
-        ms.ss_ready = true;
-
-        logger.debug("MacroState ["+ms+"] now has "+ms.ssMap.size()+" SubStates in array of size " + ms.substates.length);
-
-        writePINs(0);
-    }
-
-    private int readPINs() {
-        dpm.writeCommand(DuPALProto.buildREADCommand());
-        return DuPALProto.handleREADResponse(dpm.readResponse());
-    }
-
-    private int writePINs(int addr) throws DuPALBoardException {
-        int res;
-        dpm.writeCommand(DuPALProto.buildWRITECommand(addr));
-        res = DuPALProto.handleWRITEResponse(dpm.readResponse());
-
-        if(res < 0) {
-            logger.error("writePINs("+String.format("%08X", addr)+") -> FAILED!");
-            throw new DuPALBoardException("writePINs("+String.format("%08X", addr)+") command failed!");
-        }
-
-        return res;
-    }
-
-    static private String buildTag(int idx) {
-        return String.format("%02X", idx);
-    }
-
-    static private void printUnvisitedMacroStates(MacroState[] mStates) {
-        StringBuffer strBuf = new StringBuffer();
-
-        strBuf.append("The following MacroStates were not visited:\n");
-        for(int idx = 0; idx < mStates.length; idx++) {
-            if(mStates[idx] == null) {
-                strBuf.append("\t " + String.format("\t%02X\n", idx));
-            }
-        }
-
-        strBuf.append('\n');
-
-        logger.info(strBuf.toString());
-    }
-
-    static private void printStateStructure(OutputStream out, PALSpecs specs, MacroState[] mStates) throws IOException {
-        logger.info("Printing state structure.");
-
-        out.write(("Printing graph structure for " + specs.toString()+"\n").getBytes(StandardCharsets.US_ASCII));
-        for(int ms_idx = 0; ms_idx < mStates.length; ms_idx++) {
-            if(mStates[ms_idx] == null) continue;
-
-            out.write(("MacroState ["+mStates[ms_idx]+"]\n").getBytes(StandardCharsets.US_ASCII));
-            out.write(("\tPrinting SubStates\n").getBytes(StandardCharsets.US_ASCII));
-            for(int ss_idx = 0; ss_idx < mStates[ms_idx].substates.length; ss_idx++) {
-                if(mStates[ms_idx].substates[ss_idx] != null) out.write(("\t\tSubState ("+ss_idx+") ["+mStates[ms_idx].substates[ss_idx]+"]\n").getBytes(StandardCharsets.US_ASCII));
-            }
-            out.write(("\n").getBytes(StandardCharsets.US_ASCII));
-
-            out.write(("\tPrinting StateLinks\n").getBytes(StandardCharsets.US_ASCII));
-            for(int sl_idx = 0; sl_idx < mStates[ms_idx].links.length; sl_idx++) {
-                if(mStates[ms_idx].links[sl_idx] != null) out.write(("\t\tStateLink ("+sl_idx+") ["+mStates[ms_idx].links[sl_idx]+"] -> ["+mStates[ms_idx].links[sl_idx].destMS+"]\n").getBytes(StandardCharsets.US_ASCII));
-            }
-            out.write(("\n").getBytes(StandardCharsets.US_ASCII));
-        }
-    }
-
-    static private void printLogicTable(OutputStream out, PALSpecs specs, int ioOUTMask, MacroState[] mStates) throws IOException {
-        logger.info("Printing logic table. ");
-
-        int pinIOasOUT = countHIBits(ioOUTMask);
-        
-        out.write(("# "+specs+" logic table\n").getBytes(StandardCharsets.US_ASCII));
-        int totInputs = specs.getNumINPins() + (specs.getNumIOPins()  - pinIOasOUT);
-        StringBuffer strBuf = new StringBuffer();
-        
-        out.write((".i " + (totInputs + specs.getNumROUTPins()) + "\n").getBytes(StandardCharsets.US_ASCII));
-        out.write((".o " + (specs.getNumROUTPins() + (pinIOasOUT + specs.getNumOUTPins()) * 2) + "\n").getBytes(StandardCharsets.US_ASCII));
-
-        // Input labels
-        strBuf.delete(0, strBuf.length()); 
-        strBuf.append(".ilb ");
-        for(int idx = 0; idx < specs.getNumROUTPins(); idx++) strBuf.append("o_"+specs.getROUT_PinNames()[idx]+" "); // Old registerd states
-        for(int idx = 0; idx < specs.getIN_PinNames().length; idx++) {
-            if(((specs.getINMask() >> idx) & 0x01) != 0) strBuf.append(specs.getIN_PinNames()[idx] + " ");
-        }
-
-        if(totInputs > specs.getNumINPins()) { // IOs as inputs
-            int ioINMask = specs.getIO_READMask() & ~ioOUTMask;
-            for(int idx = 0; idx < specs.getIO_PinNames().length; idx++) {
-                if(((ioINMask >> idx) & 0x01) > 0) strBuf.append(specs.getIO_PinNames()[idx] + " ");
-            }
-        }
-        strBuf.append('\n');
-        out.write(strBuf.toString().getBytes(StandardCharsets.US_ASCII));
-        
-        // Output labels
-        strBuf.delete(0, strBuf.length());
-        strBuf.append(".ob ");
-        // registered outputs
-        for(int idx = 0; idx < specs.getNumROUTPins(); idx++) strBuf.append(specs.getROUT_PinNames()[idx]+" ");
-        for(int idx = 0; idx < specs.getIO_PinNames().length; idx++) if(((ioOUTMask >> idx) & 0x01) > 0) strBuf.append(specs.getIO_PinNames()[idx] + " ");
-        for(int idx = 0; idx < specs.getOUT_PinNames().length; idx++) if(((specs.getOUT_READMask() >> idx) & 0x01) > 0) strBuf.append(specs.getOUT_PinNames()[idx] + " ");
-        for(int idx = 0; idx < specs.getIO_PinNames().length; idx++) if(((ioOUTMask >> idx) & 0x01) > 0) strBuf.append(specs.getIO_PinNames()[idx] + ".oe ");
-        for(int idx = 0; idx < specs.getOUT_PinNames().length; idx++) if(((specs.getOUT_READMask() >> idx) & 0x01) > 0) strBuf.append(specs.getOUT_PinNames()[idx] + ".oe ");
-
-        strBuf.append("\n");
-
-        // Phase, if the chip is active low, we'll be interested in the equations that gives us the OFF-set of the truth table
-        strBuf.append(".phase ");
-        for(int idx = 0; idx < specs.getNumROUTPins(); idx++) strBuf.append(specs.isActiveLow() ? '0' : '1'); // REG outputs
-        for(int idx = 0; idx < (pinIOasOUT+specs.getNumOUTPins()); idx++) strBuf.append(specs.isActiveLow() ? '0' : '1'); // Outputs
-        for(int idx = 0; idx < (pinIOasOUT+specs.getNumOUTPins()); idx++) strBuf.append('1'); // OEs
-        strBuf.append("\n\n");
-        out.write(strBuf.toString().getBytes(StandardCharsets.US_ASCII));   
-        
-        // Table
-        for(int ms_idx = 0; ms_idx < mStates.length; ms_idx++) {
-            MacroState ms = mStates[ms_idx];
-                if(ms == null) { // This state was not explored, so we're marking its outputs ad "don't care"
-                    for(int fake_sl_idx = 0; fake_sl_idx < (1 << totInputs); fake_sl_idx++) {
-                        strBuf.delete(0, strBuf.length());
-                    
-                        // Old registered outputs
-                        for(int bit_idx = 0; bit_idx < specs.getNumROUTPins(); bit_idx++) {
-                            strBuf.append(((ms_idx >> ((specs.getNumROUTPins() - 1) - bit_idx)) & 0x01) > 0 ? '1' : '0');
-                        }
-                        // Inputs
-                        for(int bit_idx = 0; bit_idx < totInputs; bit_idx++) strBuf.append(((fake_sl_idx >> bit_idx) & 0x01) > 0 ? '1' : '0');
-
-                        strBuf.append(' ');
-                        
-                        // Fake Outputs
-                        for(int bit_idx = 0; bit_idx < specs.getNumROUTPins(); bit_idx++) strBuf.append('-');
-                        
-                        // Fake digital outputs + hi-z outputs
-                        for(int bit_idx = 0; bit_idx < (pinIOasOUT+specs.getNumOUTPins()); bit_idx++) strBuf.append("--");
-
-                        strBuf.append('\n');
-                        out.write(strBuf.toString().getBytes(StandardCharsets.US_ASCII));
-                    }
-            } else { // This state was explored
-                for(int ss_idx = 0; ss_idx < ms.links.length; ss_idx++) {
-                    SubState ss = ms.substates[ss_idx];
-                    strBuf.delete(0, strBuf.length());
-
-                    // Add the registered outputs as inputs
-                    for(int bit_idx = 0; bit_idx < specs.getNumROUTPins(); bit_idx++) {
-                        strBuf.append(((mStates[ms_idx].rpin_status >> ((specs.getNumROUTPins() - 1) - bit_idx)) & 0x01) > 0 ? '1' : '0');
-                    }
-
-                    // Add the inputs as inputs
-                    for(int bit_idx = 0; bit_idx < totInputs; bit_idx++) strBuf.append(((ss_idx >> bit_idx) & 0x01) > 0 ? '1' : '0');
-
-                    strBuf.append(' ');
-
-                    // Add the registered outputs of the new state as outputs
-                    for(int bit_idx = 0; bit_idx < specs.getNumROUTPins(); bit_idx++) {
-                        strBuf.append(((mStates[ms_idx].links[ss_idx].destMS.rpin_status >> ((specs.getNumROUTPins() - 1) - bit_idx)) & 0x01) > 0 ? '1' : '0');
-                    }
-
-                    // Add the IO as outputs
-                    for(int bit_idx = 0; bit_idx < ss.IOpin_status.length; bit_idx++) {
-                        if(ss.IOpin_status[bit_idx] == 0) strBuf.append('0');
-                        else if (ss.IOpin_status[bit_idx] > 0) strBuf.append('1');
-                        else strBuf.append('-');
-                    }
-
-                    // Add the outputs
-                    for(int bit_idx = 0; bit_idx < ss.Opin_status.length; bit_idx++) {
-                        if(ss.Opin_status[bit_idx] == 0) strBuf.append('0');
-                        else if (ss.Opin_status[bit_idx] > 0) strBuf.append('1');
-                        else strBuf.append('-');
-                    }
-                    
-                    // Add the hi-z state of IOs as output
-                    for(int bit_idx = 0; bit_idx < ss.IOpin_status.length; bit_idx++) {
-                        if(ss.IOpin_status[bit_idx] >= 0) strBuf.append('1');
-                        else strBuf.append('0');
-                    }
-
-                    // Add the hi-z state of the outputs
-                    for(int bit_idx = 0; bit_idx < ss.Opin_status.length; bit_idx++) {
-                        if(ss.Opin_status[bit_idx] >= 0) strBuf.append('1');
-                        else strBuf.append('0');
-                    }
-
-                    strBuf.append('\n');
-                    out.write(strBuf.toString().getBytes(StandardCharsets.US_ASCII));
-                }
-            }
-        }
-
-        out.write(".e\n".getBytes(StandardCharsets.US_ASCII));
     }
 }

+ 0 - 111
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL10L8Specs.java

@@ -1,111 +0,0 @@
-package info.hkzlab.dupal.analyzer.devices;
-
-public class PAL10L8Specs implements PALSpecs {
-
-    public static final String PAL_TYPE = "10L8";
-
-    private static final String[] ROUT_PIN_NAMES = { };
-    private static final String[] IN_PIN_NAMES = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i11" };
-    private static final String[] IO_PIN_NAMES = { };
-    private static final String[] OUT_PIN_NAMES = { "o18", "o17", "o16", "o15", "o14", "o13", "o19", "o12" };
-
-    @Override
-    public int getNumINPins() {
-        return 10;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 0;
-    }
-
-    @Override
-    public int getNumROUTPins() {
-        return 0;
-    }
-
-    @Override
-    public int getNumOUTPins() {
-        return 8;
-    }
-    
-    @Override
-    public int getCLKPinMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getOEPinMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getINMask() {
-        return 0x000003FF;
-    }
-
-    @Override
-    public int getIO_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getROUT_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getOUT_READMask() {
-        return 0xFF;
-    }
-
-    @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
-    }
-
-    @Override
-    public int getROUT_READMaskShift() {
-        return 0;
-    }
-
-    @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
-    }
-
-    @Override
-    public boolean isActiveLow() {
-        return true;
-    }
-}

+ 0 - 111
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL12L6Specs.java

@@ -1,111 +0,0 @@
-package info.hkzlab.dupal.analyzer.devices;
-
-public class PAL12L6Specs implements PALSpecs {
-
-    public static final String PAL_TYPE = "12L6";
-
-    private static final String[] ROUT_PIN_NAMES = { };
-    private static final String[] IN_PIN_NAMES = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i11", null, null, null, null, null, null, "i19", "i12"};
-    private static final String[] IO_PIN_NAMES = { };
-    private static final String[] OUT_PIN_NAMES = { "o18", "o17", "o16", "o15", "o14", "o13", null, null };
-
-    @Override
-    public int getNumINPins() {
-        return 12;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 0;
-    }
-
-    @Override
-    public int getNumROUTPins() {
-        return 0;
-    }
-
-    @Override
-    public int getNumOUTPins() {
-        return 6;
-    }
-    
-    @Override
-    public int getCLKPinMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getOEPinMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getINMask() {
-        return 0x000303FF;
-    }
-
-    @Override
-    public int getIO_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getROUT_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getOUT_READMask() {
-        return 0x3F;
-    }
-
-    @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
-    }
-
-    @Override
-    public int getROUT_READMaskShift() {
-        return 0;
-    }
-
-    @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
-    }
-
-    @Override
-    public boolean isActiveLow() {
-        return true;
-    }
-}

+ 45 - 45
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL16L8Specs.java

@@ -4,108 +4,108 @@ public class PAL16L8Specs implements PALSpecs {
 
     public static final String PAL_TYPE = "16L8";
 
-    private static final String[] ROUT_PIN_NAMES = { };
-    private static final String[] IN_PIN_NAMES = { "i1", "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9", "i11" };
-    private static final String[] IO_PIN_NAMES = { "io18", "io17", "io16", "io15", "io14", "io13", null, null };
-    private static final String[] OUT_PIN_NAMES = { null, null, null, null, null, null, "o19", "o12" };
+    private static final String[] LABELS_RO = { };
+    private static final String[] LABELS_IN =  {  "i1",  "i2",  "i3",  "i4",  "i5",  "i6",  "i7",  "i8",  "i9", "i11",   null,   null,   null,   null,   null,   null,   null,   null };
+    private static final String[] LABELS_IO =  {  null,  null,  null,  null,  null,  null,  null,  null,  null,  null, "io18", "io17", "io16", "io15", "io14", "io13",   null,   null };
+    private static final String[] LABELS_O  = {  null,  null,  null,  null,  null,  null,  null,  null,  null,  null,   null,   null,   null,   null,   null,   null,  "o19",  "o12" };
 
     @Override
-    public int getNumINPins() {
-        return 10;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 6;
+    public String toString() {
+        return "PAL"+PAL_TYPE;
     }
 
     @Override
-    public int getNumROUTPins() {
-        return 0;
+    public boolean isActiveLow() {
+        return true;
     }
 
     @Override
-    public int getNumOUTPins() {
-        return 2;
-    }
-    
-    @Override
-    public int getCLKPinMask() {
+    public int getMask_CLK() {
         return 0x00;
     }
 
     @Override
-    public int getOEPinMask() {
+    public int getMask_OE() {
         return 0x00;
     }
 
     @Override
-    public int getINMask() {
-        return 0x000003FF;
+    public int getMask_IN() {
+        return 0x3FF;
     }
 
     @Override
-    public int getIO_READMask() {
+    public int getMask_IO_R() {
         return 0x3F;
     }
 
     @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
+    public int getMask_IO_W() {
+        return 0xFC00;
     }
 
     @Override
-    public int getROUT_READMask() {
+    public int getMask_RO_R() {
         return 0x00;
     }
 
     @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
+    public int getMask_RO_W() {
+        return 0x00;
     }
 
     @Override
-    public int getOUT_READMask() {
+    public int getMask_O_R() {
         return 0xC0;
     }
 
     @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
+    public int getMask_O_W() {
+        return 0x30000;
     }
 
     @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
+    public String[] getLabels_RO() {
+        return LABELS_RO;
     }
 
     @Override
-    public int getROUT_READMaskShift() {
-        return 0;
+    public String[] getLabels_O() {
+        return LABELS_O;
     }
 
     @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
+    public String[] getLabels_IO() {
+        return LABELS_IO;
     }
 
     @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
+    public String[] getLabels_IN() {
+        return LABELS_IN;
     }
 
     @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
+    public int getPinCount_IN() {
+        return 10;
     }
 
     @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
+    public int getPinCount_IO() {
+        return 6;
     }
 
     @Override
-    public boolean isActiveLow() {
-        return true;
+    public int getPinCount_O() {
+        return 2;
+    }
+
+    @Override
+    public int getPinCount_RO() {
+        return 0;
+    }
+
+    @Override
+    public int minimumBoardRev() {
+        return 1;
     }
 }

+ 0 - 111
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL16R4Specs.java

@@ -1,111 +0,0 @@
-package info.hkzlab.dupal.analyzer.devices;
-
-public class PAL16R4Specs implements PALSpecs {
-
-    public static final String PAL_TYPE = "16R4";
-
-    private static final String[] ROUT_PIN_NAMES = { "ro14", "ro15", "ro16", "ro17" };
-    private static final String[] IN_PIN_NAMES = { null, "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9" };
-    private static final String[] IO_PIN_NAMES = { "io18", null, null, null, null, "io13", "io19", "io12" };
-    private static final String[] OUT_PIN_NAMES = { };
-
-    @Override
-    public int getNumINPins() {
-        return 8;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 4;
-    }
-
-    @Override
-    public int getNumROUTPins() {
-        return 4;
-    }
-    
-    @Override
-    public int getNumOUTPins() {
-        return 0;
-    }
-
-    @Override
-    public int getCLKPinMask() {
-        return 0x00000001;
-    }
-
-    @Override
-    public int getOEPinMask() {
-        return 0x00000200;
-    }
-
-    @Override
-    public int getINMask() {
-        return 0x000001FE;
-    }
-
-    @Override
-    public int getIO_READMask() {
-        return 0xE1;
-    }
-
-    @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getOUT_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getROUT_READMask() {
-        return 0x1E;
-    }
-
-    @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
-    }
-
-    @Override
-    public int getROUT_READMaskShift() {
-        return 1;
-    }
-
-    @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
-    }
-
-    @Override
-    public boolean isActiveLow() {
-        return true;
-    }
-}

+ 0 - 111
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL16R6Specs.java

@@ -1,111 +0,0 @@
-package info.hkzlab.dupal.analyzer.devices;
-
-public class PAL16R6Specs implements PALSpecs {
-
-    public static final String PAL_TYPE = "16R6";
-
-    private static final String[] ROUT_PIN_NAMES = { "ro13", "ro14", "ro15", "ro16", "ro17", "ro18" };
-    private static final String[] IN_PIN_NAMES = { null, "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9" };
-    private static final String[] IO_PIN_NAMES = { null, null, null, null, null, null, "io19", "io12" };
-    private static final String[] OUT_PIN_NAMES = { };
-
-    @Override
-    public int getNumINPins() {
-        return 8;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 2;
-    }
-
-    @Override
-    public int getNumROUTPins() {
-        return 6;
-    }
-
-    @Override
-    public int getNumOUTPins() {
-        return 0;
-    }
-
-    @Override
-    public int getCLKPinMask() {
-        return 0x00000001;
-    }
-
-    @Override
-    public int getOEPinMask() {
-        return 0x00000200;
-    }
-
-    @Override
-    public int getINMask() {
-        return 0x000001FE;
-    }
-
-    @Override
-    public int getIO_READMask() {
-        return 0xC0;
-    }
-
-    @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getOUT_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getROUT_READMask() {
-        return 0x3F;
-    }
-
-    @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
-    }
-
-    @Override
-    public int getROUT_READMaskShift() {
-        return 0;
-    }
-
-    @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
-    }
-
-    @Override
-    public boolean isActiveLow() {
-        return true;
-    }
-}

+ 0 - 111
src/main/java/info/hkzlab/dupal/analyzer/devices/PAL16R8Specs.java

@@ -1,111 +0,0 @@
-package info.hkzlab.dupal.analyzer.devices;
-
-public class PAL16R8Specs implements PALSpecs {
-
-    public static final String PAL_TYPE = "16R8";
-
-    private static final String[] ROUT_PIN_NAMES = { "ro12", "ro19" ,"ro13", "ro14", "ro15", "ro16", "ro17", "ro18" };
-    private static final String[] IN_PIN_NAMES = { null, "i2", "i3", "i4", "i5", "i6", "i7", "i8", "i9" };
-    private static final String[] IO_PIN_NAMES = { };
-    private static final String[] OUT_PIN_NAMES = { };
-
-    @Override
-    public int getNumINPins() {
-        return 8;
-    }
-
-    @Override
-    public int getNumIOPins() {
-        return 0;
-    }
-
-    @Override
-    public int getNumROUTPins() {
-        return 8;
-    }
-
-    @Override
-    public int getNumOUTPins() {
-        return 0;
-    }
-    
-    @Override
-    public int getCLKPinMask() {
-        return 0x00000001;
-    }
-
-    @Override
-    public int getOEPinMask() {
-        return 0x00000200;
-    }
-
-    @Override
-    public int getINMask() {
-        return 0x000001FE;
-    }
-
-    @Override
-    public int getIO_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getIO_WRITEMask() {
-        return getIO_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getROUT_READMask() {
-        return 0xFF;
-    }
-
-    @Override
-    public int getROUT_WRITEMask() {
-        return getROUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public int getOUT_READMask() {
-        return 0x00;
-    }
-
-    @Override
-    public int getOUT_WRITEMask() {
-        return getOUT_READMask() << READ_WRITE_SHIFT;
-    }
-
-    @Override
-    public String toString() {
-        return "PAL"+PAL_TYPE;
-    }
-
-    @Override
-    public int getROUT_READMaskShift() {
-        return 0;
-    }
-
-    @Override
-    public String[] getROUT_PinNames() {
-        return ROUT_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIN_PinNames() {
-        return IN_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getIO_PinNames() {
-        return IO_PIN_NAMES;
-    }
-
-    @Override
-    public String[] getOUT_PinNames() {
-        return OUT_PIN_NAMES;
-    }
-
-    @Override
-    public boolean isActiveLow() {
-        return true;
-    }
-}

+ 35 - 23
src/main/java/info/hkzlab/dupal/analyzer/devices/PALSpecs.java

@@ -1,29 +1,41 @@
 package info.hkzlab.dupal.analyzer.devices;
 
 public interface PALSpecs {
-    public static final int READ_WRITE_SHIFT = 10;
-
-    public int getNumINPins();
-    public int getNumIOPins();
-    public int getNumOUTPins();
-    public int getNumROUTPins();
-
-    public int getCLKPinMask();
-    public int getOEPinMask();
-    public int getINMask();
-    public int getIO_READMask();
-    public int getIO_WRITEMask();
-    public int getROUT_READMask();
-    public int getROUT_WRITEMask();
-    public int getOUT_WRITEMask();
-    public int getOUT_READMask();
-
-    public int getROUT_READMaskShift();
-
-    public String[] getROUT_PinNames();
-    public String[] getIN_PinNames();
-    public String[] getIO_PinNames();
-    public String[] getOUT_PinNames();
+    public int getPinCount_IN();
+    public int getPinCount_IO();
+    public int getPinCount_O();
+    public int getPinCount_RO();
+
+    public int getMask_CLK();
+    public int getMask_OE();
+    public int getMask_IN();
+    public int getMask_IO_R();
+    public int getMask_IO_W();
+    public int getMask_RO_R();
+    public int getMask_RO_W();
+    public int getMask_O_R();
+    public int getMask_O_W();
+
+    public String[] getLabels_RO();
+    public String[] getLabels_O();
+    public String[] getLabels_IO();
+    public String[] getLabels_IN();
 
     public boolean isActiveLow();
+
+    public int minimumBoardRev();
+
+    static public int consolidateField(int field, int mask) {
+        int data = 0;
+        int shift = 0;
+
+        for(int idx = 0; idx < 32; idx++) {
+            if(((mask >> idx) & 0x01) != 0) {
+                data |= (field >> (idx-shift)) & (1 << shift);
+                shift++;
+            }
+        }
+
+        return data;
+    }
 }

+ 0 - 79
src/main/java/info/hkzlab/dupal/analyzer/palanalisys/MacroState.java

@@ -1,79 +0,0 @@
-package info.hkzlab.dupal.analyzer.palanalisys;
-
-import java.io.Serializable;
-import java.util.HashMap;
-
-public class MacroState implements Serializable { 
-    private static final long serialVersionUID = 2L;
-
-    public static final String MS_PRE_TAG = "MS_";
-
-    public boolean ss_ready = false;
-
-    public final String tag;
-    public final int rpins;
-    public final int rpin_status;
-
-    public final SubState[] substates;
-    public final StateLink[] links;
-    public int link_count;
-    public int last_link_idx;
-    public final HashMap<Integer, SubState> ssMap;
-
-    public MacroState(final String tag, final int rpin_status, final int rpins, final int inPins) {
-        this.tag = tag;
-        this.rpin_status = rpin_status;
-        this.rpins = rpins;
-
-        links = new StateLink[1 << inPins]; // Create space for the future links out of this
-        substates = new SubState[1 << inPins]; // Create space for substates (each output pin is 3-state, but as they're triggered via input changes, we can have at most 2^inPins)
-        ssMap = new HashMap<>(); // Prepare the hashmap we'll use to avoid substate duplicates
-
-        this.link_count = 0;
-        this.last_link_idx = 0;
-
-        ss_ready = false;
-    }
-
-    @Override
-    public String toString() {
-        return MS_PRE_TAG + tag;
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = 0;
-
-        for (int idx = 0; idx < (1 << rpins); idx++) {
-            hash ^= (((rpin_status >> idx) & 0x01) << (idx % 32));
-        }
-
-        return hash ^ tag.hashCode();
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o)
-            return true;
-        if (o == null)
-            return false;
-        if (this.getClass() != o.getClass())
-            return false;
-
-        final MacroState ops = (MacroState) o;
-        if(ops.rpin_status != this.rpin_status) return false;
-        if(!ops.tag.equals(this.tag)) return false;
-
-        return true;
-    }
-
-    public static int calculateMacroStateIndex(boolean[] rpinStatus) {
-        int index = 0;
-
-        for(int idx = 0; idx < rpinStatus.length; idx++) {
-            index |= ((rpinStatus[idx] ? 1:0) << idx);
-        }
-
-        return index;
-    }    
-}

+ 0 - 45
src/main/java/info/hkzlab/dupal/analyzer/palanalisys/StateLink.java

@@ -1,45 +0,0 @@
-package info.hkzlab.dupal.analyzer.palanalisys;
-
-import java.io.Serializable;
-
-public class StateLink implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    public static final String SL_PRE_TAG = "SL_";
-
-    public final String tag;
-    public final int raw_addr;
-    public final MacroState destMS;
-
-    public StateLink(final String tag, final int raw_addr, final MacroState destMS) {
-        this.tag = tag;
-        this.raw_addr = raw_addr;
-        this.destMS = destMS;
-    }
-
-    @Override
-    public String toString() {
-        return (SL_PRE_TAG + tag + "-" + String.format("%08X", raw_addr));
-    }
-
-    @Override
-    public int hashCode() {
-        return raw_addr ^ tag.hashCode();
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o)
-            return true;
-        if (o == null)
-            return false;
-        if (this.getClass() != o.getClass())
-            return false;
-
-        final StateLink ops = (StateLink) o;
-        if(ops.raw_addr != this.raw_addr) return false;
-        if(!ops.tag.equals(this.tag)) return false;
-
-        return true;
-    }
-}

+ 0 - 15
src/main/java/info/hkzlab/dupal/analyzer/palanalisys/StatesContainer.java

@@ -1,15 +0,0 @@
-package info.hkzlab.dupal.analyzer.palanalisys;
-
-import java.io.Serializable;
-
-public class StatesContainer implements Serializable {
-    private static final long serialVersionUID = 1L;
-    
-    public final MacroState[] mStates;
-    public final String palName;
-    
-    public StatesContainer(final int mStatesCount, final String palName) {
-        this.mStates = new MacroState[mStatesCount];
-        this.palName = palName;
-    }
-}

+ 0 - 89
src/main/java/info/hkzlab/dupal/analyzer/palanalisys/SubState.java

@@ -1,89 +0,0 @@
-package info.hkzlab.dupal.analyzer.palanalisys;
-
-import java.io.Serializable;
-import java.util.Arrays;
-
-public class SubState implements Serializable {
-    private static final long serialVersionUID = 1L;
-
-    public static final String SS_PRE_TAG = "SS_";
-
-    public final String tag;
-    public final MacroState macroState;
-    public final Byte[] IOpin_status;
-    public final Byte[] Opin_status;
-
-    public SubState(final String tag, final MacroState macroState, final Byte[] IOpin_status, final Byte[] Opin_status) {
-        this.tag = tag;
-        this.macroState = macroState;
-        this.IOpin_status = IOpin_status;
-        this.Opin_status = Opin_status;
-    } 
-
-    @Override
-    public String toString() {
-        StringBuffer strBuf = new StringBuffer();
-        strBuf.append(SS_PRE_TAG+tag+"-");
-
-        if(IOpin_status.length > 0) {
-            for(byte pin : IOpin_status) {
-                if(pin < 0) strBuf.append('x');
-                else if (pin == 0) strBuf.append(0);
-                else strBuf.append(1);
-            }
-        } else strBuf.append("noIO");
-
-        strBuf.append("_");
-        
-        if(Opin_status.length > 0) {
-            for(byte pin : Opin_status) {
-                if(pin < 0) strBuf.append('x');
-                else if (pin == 0) strBuf.append(0);
-                else strBuf.append(1);
-            }
-        } else strBuf.append("noO");
-
-        return strBuf.toString();
-    }
-
-    @Override
-    public int hashCode() {
-        return calculateHashFromArrays(new Byte[][] {IOpin_status, Opin_status});
-    }
-
-    static public int calculateHashFromArrays(Byte[][] arrays) {
-        int hash = 7;
-
-        for(Byte[] arr : arrays) {
-            for(int idx = 0; idx < arr.length; idx++) {
-                hash = hash*31 + arr[idx];
-            }
-        }
-
-        return hash;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if(this == o) return true;
-        if(o == null) return false;
-        if(this.getClass() != o.getClass()) return false;
-
-        SubState ops = (SubState)o;
-        if(!ops.tag.equals(this.tag)) return false;
-        if(!Arrays.equals(ops.IOpin_status, this.IOpin_status)) return false;
-        if(!Arrays.equals(ops.Opin_status, this.Opin_status)) return false;
-
-        return true;
-    }
-
-    public static int calculateSubStateIndex(final boolean[] inputs) {
-        int index = 0;
-
-        for(int idx = 0; idx < inputs.length; idx++) {
-            index += ((inputs[idx] ? 1 : 0) << idx);
-        }
-
-        return index;
-    }
-}