Kaynağa Gözat

Add untested support for PAL12L6 and update json dependency

Fabio Battaglia 1 yıl önce
ebeveyn
işleme
217e2758e7

+ 57 - 44
.classpath

@@ -1,44 +1,57 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry kind="src" output="target/classes" path="src/main/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="test" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
-		<attributes>
-			<attribute name="maven.pomderived" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" path="target/generated-sources/annotations">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="ignore_optional_problems" value="true"/>
-			<attribute name="m2e-apt" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
-		<attributes>
-			<attribute name="optional" value="true"/>
-			<attribute name="maven.pomderived" value="true"/>
-			<attribute name="ignore_optional_problems" value="true"/>
-			<attribute name="m2e-apt" value="true"/>
-			<attribute name="test" value="true"/>
-		</attributes>
-	</classpathentry>
-	<classpathentry kind="output" path="target/classes"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" output="target/classes" path="src/main/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="src/test/java">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="target/generated-sources/annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
+		<attributes>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="test" value="true"/>
+			<attribute name="optional" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
+		<attributes>
+			<attribute name="optional" value="true"/>
+			<attribute name="maven.pomderived" value="true"/>
+			<attribute name="ignore_optional_problems" value="true"/>
+			<attribute name="m2e-apt" value="true"/>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="target/classes"/>
+</classpath>

+ 34 - 34
.project

@@ -1,34 +1,34 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
-	<name>dupal-analyzer</name>
-	<comment></comment>
-	<projects>
-	</projects>
-	<buildSpec>
-		<buildCommand>
-			<name>org.eclipse.jdt.core.javabuilder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-		<buildCommand>
-			<name>org.eclipse.m2e.core.maven2Builder</name>
-			<arguments>
-			</arguments>
-		</buildCommand>
-	</buildSpec>
-	<natures>
-		<nature>org.eclipse.jdt.core.javanature</nature>
-		<nature>org.eclipse.m2e.core.maven2Nature</nature>
-	</natures>
-	<filteredResources>
-		<filter>
-			<id>1599250965088</id>
-			<name></name>
-			<type>30</type>
-			<matcher>
-				<id>org.eclipse.core.resources.regexFilterMatcher</id>
-				<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
-			</matcher>
-		</filter>
-	</filteredResources>
-</projectDescription>
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>dupal-analyzer</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.m2e.core.maven2Builder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.m2e.core.maven2Nature</nature>
+	</natures>
+	<filteredResources>
+		<filter>
+			<id>1704211269270</id>
+			<name></name>
+			<type>30</type>
+			<matcher>
+				<id>org.eclipse.core.resources.regexFilterMatcher</id>
+				<arguments>node_modules|\.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>

+ 116 - 116
README.md

@@ -1,116 +1,116 @@
-# DuPAL Analyzer
-
-## DISCLAIMER
-
-Any use of this project is **under your own responsibility**.
-
-You are expected to have enough knowledge to be able to build this yourself (it's a Maven project: search engines are your friend), to understand what it is supposed to do, to understand it is **no magical tool that transforms a read-protected chip into a dump**, to understand truth tables and basic minimization.
-
-Please, **do not come to me asking for hand-holding** using or building this: my time is limited.
-
-Keep in mind that, while the project supports a set of PAL devices, you might wish to modify it to support a specific configuration of a GAL, or even reading of other types of chip. This is on you and you will need basic Java knowledge to accomplish it.
-
-## Introduction
-
-The **DuPAL Analyzer** is a companion software to the **DuPAL** board.
-It uses the board's *REMOTE CONTROL* mode to remotely toggle the pins and read the outputs, and is meant to perform **blackbox analisys** on the registered PAL devices, which are a bit too much for the MCU firmware to handle by itself.
-
-### What this is NOT
-
-Despite the "DUmper" part of the name, this tool is **NOT** meant to produce 1:1 binary dumps of the content of a PAL device, it is meant as an aid to the reversing procedure of an unknown PAL, automating a good part of the black box analisys.
-
-It will produce a JSON file containing every recorded state change of the PAL (outputs states at the beginning, applied inputs and output states at the end), that can then be converted into an espresso truth table or manipulated for further analisys.
-
-### Limitations
-
-The current DuPAL hardware is able to register only **STABLE** states out of a PAL device. Also, pins feeding back into themselves are **NOT** supported.
-
-To see what this means, please have a look at the [analysis](docs/analysis.md) document.
-
-Also note that, as of now, SR latches with multiple set-reset conditions seems to confuse the analyzer. See issue [#3](https://github.com/DuPAL-PAL-DUmper/DuPAL_Analyzer/issues/3).
-
-## The Analyzer
-
-The analyzer lets the user select which type of PAL is inserted in the board's ZIF socket, whether the IO pins that are set as outputs are known (which saves some time by avoiding autodetection), what is the board's serial interface, and where to save the output file.
-Once this is known, the application will:
-
-1. Connect to the board, reset it, and enable the *REMOTE MODE*, so it accepts command from the application.
-2. If which I/O pins are actually outputs is not known, the board will try to guess this and print the result. This procedure is not bulletproof (or it would take the same time as the proper analisys: in case it did not detect some outputs, these will be found during the analisys and will halt the procedure, allowing the user to specify them correctly for the next run).
-3. The analisys will start. The procedure can take hours to complete.
-4. A JSON file that collects every state of the outputs of the PAL and how they change depending on the inputs is saved to file.
-
-### Supported devices
-
-The following PAL models are supported:
-
-#### Combinatorial
-
-- PAL10L8
-- PAL16L8
-- PAL20L8
-
-#### Registered
-
-- PAL16R4
-- PAL16R6
-- PAL16R8
-- PAL20R4
-- PAL20R6
-- PAL20R8
-
-### Command line
-
-The format for command line execution is the following:
-
-```text
-java -jar /path/to/dupal_analyzer.jar <serial_port> <pal_type> [<output_file> hex_output_mask]
-```
-
-- **serial_port:** is just the serial port to use to connect to the DuPAL board. Connection is hardcoded at **57600bps 8n1** without flow control.
-- **pal_type:** is the type of PAL device that is going to be analyzed.
-- **output_file:** The file where the analyzer will save the JSON output.
-- **hex_output_mask:** This mask (a byte represented as an *hex number*) is used to tell the Analyzer which IOs are configured as outputs. If it's not present, the Analyzer will try to guess it by itself. It's usually advisable to let the guessing run for a few minutes, then restart the analisys by specifying the guessed mask. If the mask is wrong, during the analisys an error will be thrown as soon as what was thought as an input is found to be an output. At that point the analisys can be restarted with the new mask.
-
-#### The output mask format
-
-The output mask is a byte represented as an hex value, where a bit is set when the corrisponding pin is considered an output.
-From MSB to LSB for a 20 pins PAL:
-
-```text
-   7    6    5    4    3    2    1    0
-.----.----.----.----.----.----.----.----.
-| 12 | 19 | 13 | 14 | 15 | 16 | 17 | 18 |
-'----'----'----'----'----'----'----'----'
-```
-
-From MSB to LSB for a 24 pins PAL:
-
-```text
-   7    6    5    4    3    2    1    0
-.----.----.----.----.----.----.----.----.
-| 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 |
-'----'----'----'----'----'----'----'----'
-```
-
-Setting the mask to `0x02`, for example, will notify the analyzer that pin 17 on a 20 pins PAL or pin 16 on a 24 pins PAL is configured as an OUTPUT.
-
-Pay attention to the weird position for pin 19, that position is caused by a desire to save a few lines on the firmware.
-
-#### Debugging and verbosity
-
-If you wish to increase the verbosity of the analyzer, add the following parameter to the `java` command:
-
-```text
--D"org.slf4j.simpleLogger.defaultLogLevel=debug"
-```
-
-Substitute `debug` with `trace` for an even increased verbosity. The default for this parameter is `info`.
-
-#### Requirements
-
-Make sure you have at least a **Java 1.8** compatible JRE installed and have access to your serial port devices (In linux it's usually sufficient to add your user to the `dialout` group).
-
-## Credits
-
-- Thanks to [jammarcade.net](https://www.jammarcade.net/) for hosting all those PAL dumps, I used a lot of them to test my implementation.
-- Thanks to @mesillo for taking time to read my documentation and pointing out possible improvements.
+# DuPAL Analyzer
+
+## DISCLAIMER
+
+Any use of this project is **under your own responsibility**.
+
+You are expected to have enough knowledge to be able to build this yourself (it's a Maven project: search engines are your friend), to understand what it is supposed to do, to understand it is **no magical tool that transforms a read-protected chip into a dump**, to understand truth tables and basic minimization.
+
+Please, **do not come to me asking for hand-holding** using or building this: my time is limited.
+
+Keep in mind that, while the project supports a set of PAL devices, you might wish to modify it to support a specific configuration of a GAL, or even reading of other types of chip. This is on you and you will need basic Java knowledge to accomplish it.
+
+## Introduction
+
+The **DuPAL Analyzer** is a companion software to the **DuPAL** board.
+It uses the board's *REMOTE CONTROL* mode to remotely toggle the pins and read the outputs, and is meant to perform **blackbox analisys** on the registered PAL devices, which are a bit too much for the MCU firmware to handle by itself.
+
+### What this is NOT
+
+Despite the "DUmper" part of the name, this tool is **NOT** meant to produce 1:1 binary dumps of the content of a PAL device, it is meant as an aid to the reversing procedure of an unknown PAL, automating a good part of the black box analisys.
+
+It will produce a JSON file containing every recorded state change of the PAL (outputs states at the beginning, applied inputs and output states at the end), that can then be converted into an espresso truth table or manipulated for further analisys.
+
+### Limitations
+
+The current DuPAL hardware is able to register only **STABLE** states out of a PAL device. Also, pins feeding back into themselves are **NOT** supported.
+
+To see what this means, please have a look at the [analysis](docs/analysis.md) document.
+
+Also note that, as of now, SR latches with multiple set-reset conditions seems to confuse the analyzer. See issue [#3](https://github.com/DuPAL-PAL-DUmper/DuPAL_Analyzer/issues/3).
+
+## The Analyzer
+
+The analyzer lets the user select which type of PAL is inserted in the board's ZIF socket, whether the IO pins that are set as outputs are known (which saves some time by avoiding autodetection), what is the board's serial interface, and where to save the output file.
+Once this is known, the application will:
+
+1. Connect to the board, reset it, and enable the *REMOTE MODE*, so it accepts command from the application.
+2. If which I/O pins are actually outputs is not known, the board will try to guess this and print the result. This procedure is not bulletproof (or it would take the same time as the proper analisys: in case it did not detect some outputs, these will be found during the analisys and will halt the procedure, allowing the user to specify them correctly for the next run).
+3. The analisys will start. The procedure can take hours to complete.
+4. A JSON file that collects every state of the outputs of the PAL and how they change depending on the inputs is saved to file.
+
+### Supported devices
+
+The following PAL models are supported:
+
+#### Combinatorial
+
+- PAL10L8
+- PAL16L8
+- PAL20L8
+
+#### Registered
+
+- PAL16R4
+- PAL16R6
+- PAL16R8
+- PAL20R4
+- PAL20R6
+- PAL20R8
+
+### Command line
+
+The format for command line execution is the following:
+
+```text
+java -jar /path/to/dupal_analyzer.jar <serial_port> <pal_type> [<output_file> hex_output_mask]
+```
+
+- **serial_port:** is just the serial port to use to connect to the DuPAL board. Connection is hardcoded at **57600bps 8n1** without flow control.
+- **pal_type:** is the type of PAL device that is going to be analyzed.
+- **output_file:** The file where the analyzer will save the JSON output.
+- **hex_output_mask:** This mask (a byte represented as an *hex number*) is used to tell the Analyzer which IOs are configured as outputs. If it's not present, the Analyzer will try to guess it by itself. It's usually advisable to let the guessing run for a few minutes, then restart the analisys by specifying the guessed mask. If the mask is wrong, during the analisys an error will be thrown as soon as what was thought as an input is found to be an output. At that point the analisys can be restarted with the new mask.
+
+#### The output mask format
+
+The output mask is a byte represented as an hex value, where a bit is set when the corrisponding pin is considered an output.
+From MSB to LSB for a 20 pins PAL:
+
+```text
+   7    6    5    4    3    2    1    0
+.----.----.----.----.----.----.----.----.
+| 12 | 19 | 13 | 14 | 15 | 16 | 17 | 18 |
+'----'----'----'----'----'----'----'----'
+```
+
+From MSB to LSB for a 24 pins PAL:
+
+```text
+   7    6    5    4    3    2    1    0
+.----.----.----.----.----.----.----.----.
+| 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 |
+'----'----'----'----'----'----'----'----'
+```
+
+Setting the mask to `0x02`, for example, will notify the analyzer that pin 17 on a 20 pins PAL or pin 16 on a 24 pins PAL is configured as an OUTPUT.
+
+Pay attention to the weird position for pin 19, that position is caused by a desire to save a few lines on the firmware.
+
+#### Debugging and verbosity
+
+If you wish to increase the verbosity of the analyzer, add the following parameter to the `java` command:
+
+```text
+-D"org.slf4j.simpleLogger.defaultLogLevel=debug"
+```
+
+Substitute `debug` with `trace` for an even increased verbosity. The default for this parameter is `info`.
+
+#### Requirements
+
+Make sure you have at least a **Java 1.8** compatible JRE installed and have access to your serial port devices (In linux it's usually sufficient to add your user to the `dialout` group).
+
+## Credits
+
+- Thanks to [jammarcade.net](https://www.jammarcade.net/) for hosting all those PAL dumps, I used a lot of them to test my implementation.
+- Thanks to @mesillo for taking time to read my documentation and pointing out possible improvements.

+ 160 - 160
pom.xml

@@ -1,160 +1,160 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-
-  <groupId>info.hkzlab.dupal.analyzer</groupId>
-  <artifactId>dupal-analyzer</artifactId>
-  <version>0.1.4</version>
-
-  <name>dupal-analyzer</name>
-  <url>https://github.com/DuPAL-PAL-DUmper</url>
-
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-    <maven.compiler.source>1.8</maven.compiler.source>
-    <maven.compiler.target>1.8</maven.compiler.target>
-  </properties>
-
-  <dependencies>
-    <dependency>
-      <groupId>io.github.java-native</groupId>
-      <artifactId>jssc</artifactId>
-      <version>2.9.2</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.json</groupId>
-      <artifactId>json</artifactId>
-      <version>20200518</version>
-    </dependency>
-
-    <dependency>
-     <groupId>org.slf4j</groupId>
-     <artifactId>slf4j-api</artifactId>
-     <version>1.7.30</version>
-    </dependency>
-
-    <!--dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-jdk14</artifactId>
-      <version>1.7.30</version>
-    </dependency-->
-
-    <dependency>
-     <groupId>org.slf4j</groupId>
-     <artifactId>slf4j-simple</artifactId>
-     <version>1.7.30</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.scijava</groupId>
-      <artifactId>native-lib-loader</artifactId>
-      <version>2.3.4</version>
-    </dependency>
-
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>4.13.1</version>
-      <scope>test</scope>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <version>3.5.10</version>
-     <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-junit-jupiter</artifactId>
-      <version>3.5.10</version>
-      <scope>test</scope>
-    </dependency>
-
-  </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <artifactId>maven-assembly-plugin</artifactId>
-        <executions>
-          <execution>
-            <id>make-assembly</id>
-            <phase>package</phase>
-            <goals>
-              <goal>single</goal>
-            </goals>
-          </execution>
-        </executions>
-        <configuration>
-          <archive>
-            <manifest>
-              <mainClass>info.hkzlab.dupal.analyzer.App</mainClass>
-              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-            </manifest>
-          </archive>
-          <descriptorRefs>
-            <descriptorRef>jar-with-dependencies</descriptorRef>
-          </descriptorRefs>
-        </configuration>
-      </plugin>
-    </plugins>
-    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
-      <plugins>
-        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->        
-        <plugin>
-          <artifactId>maven-clean-plugin</artifactId>
-          <version>3.1.0</version>
-        </plugin>
-        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
-        <plugin>
-          <artifactId>maven-resources-plugin</artifactId>
-          <version>3.0.2</version>
-        </plugin>
-        <plugin>
-          <artifactId>maven-compiler-plugin</artifactId>
-          <version>3.8.0</version>
-        </plugin>
-        <plugin>
-          <artifactId>maven-surefire-plugin</artifactId>
-          <version>2.22.1</version>
-        </plugin>
-        <plugin>
-          <artifactId>maven-jar-plugin</artifactId>
-          <version>3.0.2</version>				
-          <configuration>
-					  <archive>
-						  <manifest>
-							  <mainClass>info.hkzlab.dupal.analyzer.App</mainClass>
-                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
-                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
-						  </manifest>
-					  </archive>
-				  </configuration>
-        </plugin>
-        <plugin>
-          <artifactId>maven-install-plugin</artifactId>
-          <version>2.5.2</version>
-        </plugin>
-        <plugin>
-          <artifactId>maven-deploy-plugin</artifactId>
-          <version>2.8.2</version>
-        </plugin>
-        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
-        <plugin>
-          <artifactId>maven-site-plugin</artifactId>
-          <version>3.7.1</version>
-        </plugin>
-        <plugin>
-          <artifactId>maven-project-info-reports-plugin</artifactId>
-          <version>3.0.0</version>
-        </plugin>
-      </plugins>
-    </pluginManagement>
-  </build>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <groupId>info.hkzlab.dupal.analyzer</groupId>
+  <artifactId>dupal-analyzer</artifactId>
+  <version>0.1.5</version>
+
+  <name>dupal-analyzer</name>
+  <url>https://github.com/DuPAL-PAL-DUmper</url>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>io.github.java-native</groupId>
+      <artifactId>jssc</artifactId>
+      <version>2.9.2</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.json</groupId>
+      <artifactId>json</artifactId>
+      <version>[20231013,)</version>
+    </dependency>
+
+    <dependency>
+     <groupId>org.slf4j</groupId>
+     <artifactId>slf4j-api</artifactId>
+     <version>1.7.30</version>
+    </dependency>
+
+    <!--dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-jdk14</artifactId>
+      <version>1.7.30</version>
+    </dependency-->
+
+    <dependency>
+     <groupId>org.slf4j</groupId>
+     <artifactId>slf4j-simple</artifactId>
+     <version>1.7.30</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.scijava</groupId>
+      <artifactId>native-lib-loader</artifactId>
+      <version>2.3.4</version>
+    </dependency>
+
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.13.1</version>
+      <scope>test</scope>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>3.5.10</version>
+     <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-junit-jupiter</artifactId>
+      <version>3.5.10</version>
+      <scope>test</scope>
+    </dependency>
+
+  </dependencies>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>make-assembly</id>
+            <phase>package</phase>
+            <goals>
+              <goal>single</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <archive>
+            <manifest>
+              <mainClass>info.hkzlab.dupal.analyzer.App</mainClass>
+              <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+              <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+            </manifest>
+          </archive>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+        </configuration>
+      </plugin>
+    </plugins>
+    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
+      <plugins>
+        <!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->        
+        <plugin>
+          <artifactId>maven-clean-plugin</artifactId>
+          <version>3.1.0</version>
+        </plugin>
+        <!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
+        <plugin>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>3.0.2</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.8.0</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>2.22.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>3.0.2</version>				
+          <configuration>
+					  <archive>
+						  <manifest>
+							  <mainClass>info.hkzlab.dupal.analyzer.App</mainClass>
+                <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
+                <addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
+						  </manifest>
+					  </archive>
+				  </configuration>
+        </plugin>
+        <plugin>
+          <artifactId>maven-install-plugin</artifactId>
+          <version>2.5.2</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-deploy-plugin</artifactId>
+          <version>2.8.2</version>
+        </plugin>
+        <!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
+        <plugin>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>3.7.1</version>
+        </plugin>
+        <plugin>
+          <artifactId>maven-project-info-reports-plugin</artifactId>
+          <version>3.0.0</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>

+ 114 - 113
src/main/java/info/hkzlab/dupal/analyzer/App.java

@@ -1,113 +1,114 @@
-package info.hkzlab.dupal.analyzer;
-
-import java.io.File;
-import java.lang.reflect.InvocationTargetException;
-
-import org.slf4j.*;
-
-import info.hkzlab.dupal.analyzer.board.boardio.*;
-import info.hkzlab.dupal.analyzer.devices.*;
-
-public class App {
-    public static volatile String[] palTypes = { 
-                                                // Simple devices
-                                                PAL10L8Specs.PAL_TYPE,
-                                                PAL12H6Specs.PAL_TYPE,
-
-                                                // Asynchronous outputs
-                                                PAL16L8Specs.PAL_TYPE,
-                                                PAL20L8Specs.PAL_TYPE,
-
-                                                // Registered devices
-                                                PAL16R4Specs.PAL_TYPE,
-                                                PAL16R6Specs.PAL_TYPE,
-                                                PAL16R8Specs.PAL_TYPE,
-                                                PAL20R4Specs.PAL_TYPE,
-                                                PAL20R6Specs.PAL_TYPE,
-                                                PAL20R8Specs.PAL_TYPE 
-                                            };
-
-    private final static Logger logger = LoggerFactory.getLogger(App.class);
-
-    private final static String version = App.class.getPackage().getImplementationVersion();
-
-    private static String serialDevice = null;
-    private static PALSpecs pspecs = null;
-    private static int outMask = -1;
-    private static String outFile = null;
-
-    public static void main(String[] args) throws Exception {
-        logger.info("DuPAL Analyzer " + version);
-
-        if (args.length < 2) {
-            StringBuffer supportedPALs = new StringBuffer();
-
-            for(String palT : palTypes) {
-                supportedPALs.append("\t"+palT+"\n");
-            }
-
-            logger.error("Wrong number of arguments passed.\n"
-                    + "dupal_analyzer <serial_port> <pal_type> [<output_file> hex_output_mask]\n"
-                    + "Where <pal_type> can be:\n" + supportedPALs.toString() + "\n");
-
-            return;
-        }
-
-        parseArgs(args);
-
-        DuPALManager dpm = new DuPALManager(serialDevice);
-        DuPALCmdInterface dpci = new DuPALCmdInterface(dpm, pspecs);
-        DuPALAnalyzer dpan = new DuPALAnalyzer(dpci, outMask, outFile);
-
-        if (!dpm.enterRemoteMode()) {
-            logger.error("Unable to put DuPAL board in REMOTE MODE!");
-            System.exit(-1);
-        } 
-
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                dpci.reset();
-            }
-        });
-
-        dpan.startAnalisys();
-    }
-
-    private static void parseArgs(String[] args) {
-        serialDevice = args[0];
-
-        try {
-            Class<?> specsClass = Class.forName("info.hkzlab.dupal.analyzer.devices.PAL" + args[1].toUpperCase() + "Specs");
-            pspecs = (PALSpecs) specsClass.getConstructor().newInstance(new Object[]{});
-        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
-                | InvocationTargetException | NoSuchMethodException | SecurityException e) {
-            logger.error("Invalid PAL type selected.");
-            System.exit(-1);
-        }
-
-        if(args.length >= 4) {
-            outFile = args[2];
-            outMask = Integer.parseInt(args[3], 16);
-            
-            checkOutPath(outFile);
-        }
-    }
-
-    private static void checkOutPath(String path) {
-        File file = new File(path);
-
-        boolean exists = file.exists();
-        boolean isDirectory = file.isDirectory();
-
-        if(isDirectory) {
-            logger.error("Output path " + path + " points to a directory, please specify an output file!");
-            System.exit(-1);
-        }
-
-        if(exists) {
-            logger.error("Output path " + path + " points to an existing file. We're not going to overwrite it!");
-            System.exit(-1);
-        }
-    }
-}
+package info.hkzlab.dupal.analyzer;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+
+import org.slf4j.*;
+
+import info.hkzlab.dupal.analyzer.board.boardio.*;
+import info.hkzlab.dupal.analyzer.devices.*;
+
+public class App {
+    public static volatile String[] palTypes = { 
+                                                // Simple devices
+                                                PAL10L8Specs.PAL_TYPE,
+                                                PAL12L6Specs.PAL_TYPE,
+                                                PAL12H6Specs.PAL_TYPE,
+
+                                                // Asynchronous outputs
+                                                PAL16L8Specs.PAL_TYPE,
+                                                PAL20L8Specs.PAL_TYPE,
+
+                                                // Registered devices
+                                                PAL16R4Specs.PAL_TYPE,
+                                                PAL16R6Specs.PAL_TYPE,
+                                                PAL16R8Specs.PAL_TYPE,
+                                                PAL20R4Specs.PAL_TYPE,
+                                                PAL20R6Specs.PAL_TYPE,
+                                                PAL20R8Specs.PAL_TYPE 
+                                            };
+
+    private final static Logger logger = LoggerFactory.getLogger(App.class);
+
+    private final static String version = App.class.getPackage().getImplementationVersion();
+
+    private static String serialDevice = null;
+    private static PALSpecs pspecs = null;
+    private static int outMask = -1;
+    private static String outFile = null;
+
+    public static void main(String[] args) throws Exception {
+        logger.info("DuPAL Analyzer " + version);
+
+        if (args.length < 2) {
+            StringBuffer supportedPALs = new StringBuffer();
+
+            for(String palT : palTypes) {
+                supportedPALs.append("\t"+palT+"\n");
+            }
+
+            logger.error("Wrong number of arguments passed.\n"
+                    + "dupal_analyzer <serial_port> <pal_type> [<output_file> hex_output_mask]\n"
+                    + "Where <pal_type> can be:\n" + supportedPALs.toString() + "\n");
+
+            return;
+        }
+
+        parseArgs(args);
+
+        DuPALManager dpm = new DuPALManager(serialDevice);
+        DuPALCmdInterface dpci = new DuPALCmdInterface(dpm, pspecs);
+        DuPALAnalyzer dpan = new DuPALAnalyzer(dpci, outMask, outFile);
+
+        if (!dpm.enterRemoteMode()) {
+            logger.error("Unable to put DuPAL board in REMOTE MODE!");
+            System.exit(-1);
+        } 
+
+        Runtime.getRuntime().addShutdownHook(new Thread() {
+            @Override
+            public void run() {
+                dpci.reset();
+            }
+        });
+
+        dpan.startAnalisys();
+    }
+
+    private static void parseArgs(String[] args) {
+        serialDevice = args[0];
+
+        try {
+            Class<?> specsClass = Class.forName("info.hkzlab.dupal.analyzer.devices.PAL" + args[1].toUpperCase() + "Specs");
+            pspecs = (PALSpecs) specsClass.getConstructor().newInstance(new Object[]{});
+        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+                | InvocationTargetException | NoSuchMethodException | SecurityException e) {
+            logger.error("Invalid PAL type selected.");
+            System.exit(-1);
+        }
+
+        if(args.length >= 4) {
+            outFile = args[2];
+            outMask = Integer.parseInt(args[3], 16);
+            
+            checkOutPath(outFile);
+        }
+    }
+
+    private static void checkOutPath(String path) {
+        File file = new File(path);
+
+        boolean exists = file.exists();
+        boolean isDirectory = file.isDirectory();
+
+        if(isDirectory) {
+            logger.error("Output path " + path + " points to a directory, please specify an output file!");
+            System.exit(-1);
+        }
+
+        if(exists) {
+            logger.error("Output path " + path + " points to an existing file. We're not going to overwrite it!");
+            System.exit(-1);
+        }
+    }
+}

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

@@ -0,0 +1,116 @@
+package info.hkzlab.dupal.analyzer.devices;
+
+public class PAL12L6Specs implements PALSpecs {
+
+    public static final String PAL_TYPE = "12L6";
+
+    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,  "i19",  "i12" };
+    private static final String[] LABELS_IO =  { };
+    private static final String[] LABELS_O  =  {  null,  null,  null,  null,  null,  null,  null,  null,  null,  null,  "o18",  "o17",   "o16",   "o15",   "o14",   "o13",   null,   null };
+
+    @Override
+    public String toString() {
+        return "PAL"+PAL_TYPE;
+    }
+
+    @Override
+    public boolean isActiveLow() {
+        return true;
+    }
+
+    @Override
+    public int getMask_CLK() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_OE() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_IN() {
+        return 0x0303FF;
+    }
+
+    @Override
+    public int getMask_IO_R() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_IO_W() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_RO_R() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_RO_W() {
+        return 0x00;
+    }
+
+    @Override
+    public int getMask_O_R() {
+        return 0x3F;
+    }
+
+    @Override
+    public int getMask_O_W() {
+        return 0xFC00;
+    }
+
+    @Override
+    public String[] getLabels_RO() {
+        return LABELS_RO;
+    }
+
+    @Override
+    public String[] getLabels_O() {
+        return LABELS_O;
+    }
+
+    @Override
+    public String[] getLabels_IO() {
+        return LABELS_IO;
+    }
+
+    @Override
+    public String[] getLabels_IN() {
+        return LABELS_IN;
+    }
+
+    @Override
+    public int getPinCount_IN() {
+        return 12;
+    }
+
+    @Override
+    public int getPinCount_IO() {
+        return 0;
+    }
+
+    @Override
+    public int getPinCount_O() {
+        return 6;
+    }
+
+    @Override
+    public int getPinCount_RO() {
+        return 0;
+    }
+
+    @Override
+    public int minimumBoardRev() {
+        return 1;
+    }
+
+    @Override
+    public int slotNumber() {
+        return 0;
+    }
+}