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;