diff --git a/eeprom.json b/eeprom.json
new file mode 100644
index 0000000..0e0dcd2
--- /dev/null
+++ b/eeprom.json
@@ -0,0 +1,3 @@
+{
+
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 341d416..85afb62 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,11 @@
system
${project.basedir}/libs/com.gluon/charm-glisten-4.4.1.jar
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+
eu.hansolo
tilesfx
diff --git a/src/main/java/fabrik/simulator/pic16f84/CreateWindow.java b/src/main/java/fabrik/simulator/pic16f84/CreateWindow.java
index 4f4c386..391f472 100644
--- a/src/main/java/fabrik/simulator/pic16f84/CreateWindow.java
+++ b/src/main/java/fabrik/simulator/pic16f84/CreateWindow.java
@@ -20,15 +20,12 @@ public class CreateWindow extends Application {
@Override
- public void start(Stage primaryStage) throws IOException{
+ public void start(Stage primaryStage) throws IOException {
DataRegister.initDataRegister();
table = Table.refresh();
FXMLLoader codewindow = new FXMLLoader(CreateWindow.class.getResource("frontend.fxml"));
Parent code = codewindow.load();
-
-
-
grid.add(table, 1, 1);
grid.add(code, 0, 1);
@@ -41,19 +38,15 @@ public class CreateWindow extends Application {
primaryStage.show();
}
- static void main(String[] args) {
-
+ public static void main(String[] args) {
launch(args);
-
}
- public static void refreshTable(Stage stage) throws IOException {
+ public static void refreshTable(Stage stage) {
grid.getChildren().remove(table);
table= Table.refresh();
grid.add(table, 1, 1);
}
-
-
}
diff --git a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java
index 8c0b2f3..8b96733 100644
--- a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java
+++ b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java
@@ -12,6 +12,11 @@ public class DataRegister {
private static final int PCLATH = 0xA;
private static final int INTCON = 0xB;
+ private static final int EEDATA = 0x08;
+ private static final int EEADR = 0x09;
+ private static final int EECON1 = 0x88;
+ private static final int EECON2 = 0x89;
+
private static final int TRISA = 0x85;
private static final int TRISB = 0x86;
@@ -23,6 +28,7 @@ public class DataRegister {
private static final int [] dataRegister = new int[0xFF];
private static final int [] syncedRegisters = {INDF, PCL, STATUS, FSR, PCLATH, INTCON};
+ private static final int [] eepromRegisters = {EEDATA, EEADR, EECON1, EECON2};
public static final int [] ioRegisters = {PORTA, PORTB, TRISA, TRISB};
public static void initDataRegister() {
@@ -81,6 +87,10 @@ public class DataRegister {
IOPorts.setRegister(bank() + address, content);
return;
}
+ if (Arrays.stream(eepromRegisters).anyMatch(i -> i == address)){
+ EEPROM.parse(bank() + address, content, 0b11);
+ return;
+ }
if (fileAddress == PCL || fileAddress == 0x80 + PCL){
programCounter = content + (dataRegister[PCLATH] << 8);
}
@@ -112,6 +122,10 @@ public class DataRegister {
IOPorts.clearBit(bank() + address, bit);
return;
}
+ if (Arrays.stream(eepromRegisters).anyMatch(i -> i == address)){
+ EEPROM.parse(bank () + address, bit, 0b00);
+ return;
+ }
if (!isSyncedRegister(address)) {
if (getBit(address, bit) == 1) {
dataRegister[bank() + address] -= (int) Math.pow(2, bit);
@@ -136,6 +150,10 @@ public class DataRegister {
IOPorts.setBit(bank() + address, bit);
return;
}
+ if (Arrays.stream(eepromRegisters).anyMatch(i -> i == address)){
+ EEPROM.parse(bank () + address, bit, 0b10);
+ return;
+ }
if (!isSyncedRegister(address)) {
if (getBit(address, bit) == 0) {
dataRegister[bank() + address] += (int) Math.pow(2, bit);
diff --git a/src/main/java/fabrik/simulator/pic16f84/EEPROM.java b/src/main/java/fabrik/simulator/pic16f84/EEPROM.java
new file mode 100644
index 0000000..c47afbf
--- /dev/null
+++ b/src/main/java/fabrik/simulator/pic16f84/EEPROM.java
@@ -0,0 +1,144 @@
+package fabrik.simulator.pic16f84;
+
+
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+public class EEPROM {
+ private static final int EEDATA = 0x08;
+ private static final int EEADR = 0x09;
+ private static final int EECON1 = 0x88;
+ private static final int EECON2 = 0x89;
+
+ private static final int RD = 0x00;
+ private static final int WR = 0x01;
+ private static final int WRERR = 0x03;
+ private static final int EEIF = 0x04;
+
+ private static boolean readControl = false;
+ private static boolean writeControl = false;
+
+ public static long read (int address) {
+ FileReader reader;
+ try {
+ reader = new FileReader("eeprom.json");
+ } catch (FileNotFoundException e) {
+ return 0;
+ }
+ JSONParser parser = new JSONParser();
+ JSONObject data;
+ try {
+ data = (JSONObject) parser.parse(reader);
+ } catch (ParseException | IOException e) {
+ return 0;
+ }
+ Object requestedData = data.get(String.valueOf(address));
+ try {
+ readControl = false;
+ DataRegister.setDirectBit(EECON1, RD, 0);
+ return (long) requestedData;
+ } catch (NullPointerException e) {
+ return 0;
+ }
+ }
+
+ public static void write (int address, long data) {
+ FileReader reader;
+ try {
+ reader = new FileReader("eeprom.json");
+ } catch (FileNotFoundException ignored) {
+ DataRegister.setDirectBit(EECON1, WRERR, 1);
+ return;
+ }
+ JSONParser parser = new JSONParser();
+ JSONObject eeprom;
+ try {
+ eeprom = (JSONObject) parser.parse(reader);
+ } catch (ParseException | IOException ignored) {
+ DataRegister.setDirectBit(EECON1, WRERR, 1);
+ return;
+ }
+ eeprom.put(String.valueOf(address), data);
+ try {
+ Files.write(Paths.get("eeprom.json"), eeprom.toJSONString().getBytes());
+ } catch (IOException ignored) {
+ DataRegister.setDirectBit(EECON1, WRERR, 1);
+ return;
+ }
+ DataRegister.setDirectBit(EECON1, EEIF, 1);
+ DataRegister.setDirectBit(EECON1, WR, 0);
+ writeControl = false;
+ }
+
+ public static void parse(int address, int content, int opcode) {
+ //OPCODE: 0b1x = set
+ //OPCODE: 0b0x = clear
+ //OPCODE: 0bx1 = byte
+ //OPCODE: 0bx0 = bit
+ switch (opcode){
+ case 0b00: // CLEAR BIT
+ if(address == EECON1) {
+ if (DataRegister.getDirectBit(address, content) == 1)
+ setEECON1((int) (DataRegister.getDirectRegister(EECON1) - Math.pow(2, content)));
+ } else if (address != EECON2) {
+ DataRegister.setDirectBit(address, content, 0);
+ }
+ break;
+ case 0b10: // SET BIT
+ if(address == EECON1) {
+ if (DataRegister.getDirectBit(address, content) == 0)
+ setEECON1((int) (DataRegister.getDirectRegister(EECON1) + Math.pow(2, content)));
+ } else if (address != EECON2) {
+ if (address == EEADR && content >= 0b01000000)
+ DataRegister.setDirectBit(address, content, 0);
+ else
+ DataRegister.setDirectBit(address, content, 1);
+ }
+ break;
+ case 0b11: // SET BYTE
+ if(address == EECON1) {
+ setEECON1 (content);
+ } else if (address != EECON2) {
+ if (address == EEADR)
+ content &= 0b00111111;
+ DataRegister.setDirectRegister(address, content);
+ }
+ break;
+ }
+ }
+
+ private static void setEECON1(int content) {
+ content &= 0b00011111;
+ boolean writeEnabled = ((content & 0b100) >> 2) == 1;
+ if ((content & 0b1) == 1) { // READ
+ readControl = true;
+ DataRegister.setDirectRegister(EECON1, content);
+ int data = (int) read(DataRegister.getDirectRegister(EEADR));
+ DataRegister.setDirectRegister(EEDATA, data);
+ return;
+ }
+ else if ((content & 0b1) == 0 && readControl) // RD kann nicht manuell gecleart werden
+ content |= 0b1;
+ if (((content & 0b10) >> 1) == 1) { // WRITE CONTROL
+ if (writeEnabled) {
+ writeControl = true;
+ DataRegister.setDirectRegister(EECON1, content);
+ write(DataRegister.getDirectRegister(EEADR), DataRegister.getDirectRegister(EEDATA));
+ return;
+ }
+ else {
+ content -= 0b10;
+ }
+ }
+ else if ((((content & 0b10) >> 1) == 0) && writeControl) // WR kann nicht manuell gecleart werden
+ content |= 0b10;
+ DataRegister.setDirectRegister(EECON1, content);
+ }
+}
diff --git a/src/main/java/fabrik/simulator/pic16f84/IOPorts.java b/src/main/java/fabrik/simulator/pic16f84/IOPorts.java
index 8428b85..987e776 100644
--- a/src/main/java/fabrik/simulator/pic16f84/IOPorts.java
+++ b/src/main/java/fabrik/simulator/pic16f84/IOPorts.java
@@ -84,23 +84,40 @@ public class IOPorts {
buttonsPORT[i].setDisable(!val);
buttonsTRIS[i].getToggles().get(0).setSelected(val);
buttonsTRIS[i].getToggles().get(1).setSelected(!val);
- if(i < 8){
- if (isLEDenabledA && !val){
- if (DataRegister.getDirectBit(PORTA, i) == 1)
- allLEDsA[i].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ updateLEDs(true, i, val);
+ }
+ }
+
+ private static void updateLEDs(boolean updateAll, int index, boolean val) {
+ if (updateAll) {
+ if (index < 8) {
+ if (isLEDenabledA && !val) {
+ if (DataRegister.getDirectBit(PORTA, index) == 1)
+ allLEDsA[index].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
else
- allLEDsA[i].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
- }
- }
- else{
- if (isLEDenabledB){
- if (DataRegister.getDirectBit(PORTB, i-8) == 1)
- allLEDsB[i-8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.RED), new Stop(1, Color.DARKGRAY)));
- else
- allLEDsB[i-8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ allLEDsA[index].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ }
+ } else {
+ if (isLEDenabledB && !val) {
+ if (DataRegister.getDirectBit(PORTB, index - 8) == 1)
+ allLEDsB[index - 8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.RED), new Stop(1, Color.DARKGRAY)));
+ else
+ allLEDsB[index - 8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
}
}
}
+ else {
+ if (index < 8)
+ if (val || DataRegister.getDirectBit(PORTA, index) == 0)
+ allLEDsA[index].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ else
+ allLEDsA[index].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.RED), new Stop(1, Color.DARKGRAY)));
+ else
+ if (val || DataRegister.getDirectBit(PORTB, index - 8) == 0)
+ allLEDsB[index - 8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ else
+ allLEDsB[index - 8].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.RED), new Stop(1, Color.DARKGRAY)));
+ }
}
private static boolean isInput(int i, int bit) {
@@ -121,6 +138,7 @@ public class IOPorts {
clearBit(tris, bit);
buttonsPORT[(tris-TRISA)*8 + bit].setDisable(true);
}
+ updateLEDs(false, (tris-TRISA)*8 + bit, value == 1);
refreshPorts();
refreshTable(parent);
}
@@ -142,13 +160,13 @@ public class IOPorts {
boolean isBnowDisabled = isLEDenabledB && !leds[1];
isLEDenabledB = leds[1];
if (isAnowDisabled){
- for (int i = 0; i < allLEDsA.length; i++){
- allLEDsA[i].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ for (Circle circle : allLEDsA) {
+ circle.setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
}
}
if (isBnowDisabled){
- for (int i = 0; i < allLEDsB.length; i++){
- allLEDsB[i].setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
+ for (Circle circle : allLEDsB) {
+ circle.setFill(new RadialGradient(0, 0, 0.5, 0.5, 0.7, true, null, new Stop(0, Color.BLACK), new Stop(1, Color.DARKGRAY)));
}
}
}
@@ -158,7 +176,7 @@ public class IOPorts {
allLEDsB = b;
}
- private static void refreshTable(ToggleButtonGroup parent) throws IOException {
+ private static void refreshTable(ToggleButtonGroup parent) {
Stage stage = (Stage) parent.getScene().getWindow();
Table.refresh();
CreateWindow.refreshTable(stage);
diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java
index d03bae5..769d520 100644
--- a/src/main/java/module-info.java
+++ b/src/main/java/module-info.java
@@ -7,6 +7,8 @@ module fabrik.simulator.pic16f84 {
requires org.kordamp.ikonli.javafx;
requires eu.hansolo.tilesfx;
requires charm.glisten;
+ requires jdk.jsobject;
+ requires json.simple;
opens fabrik.simulator.pic16f84 to javafx.fxml;
exports fabrik.simulator.pic16f84;