package fabrik.simulator.pic16f84; import eu.hansolo.tilesfx.Command; 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; import fabrik.simulator.pic16f84.interfaces.*; public class EEPROM extends PICComponent implements EEPROMInterface { private final int EEDATA = 0x08; private final int EEADR = 0x09; private final int EECON1 = 0x88; private final int EECON2 = 0x89; private final int RD = 0x00; private final int WR = 0x01; private final int WRERR = 0x03; private final int EEIF = 0x04; private boolean readControl = false; private boolean writeControl = false; private boolean [] eecon2stages = {false, false}; private double startTime; public EEPROM (){ } public long read (int address) { if (address < 0) return 0; 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 void write (int address, long data) { if (address < 0) return; 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; } registerTime(true); } public void registerTime(boolean reset) { if (reset) startTime = commands.getTotalExecutionTime(); else if ((commands.getTotalExecutionTime() >= (startTime + 1000)) && writeControl) { eecon2stages = new boolean[]{false, false}; dataRegister.setDirectBit(EECON1, EEIF, 1); dataRegister.setDirectBit(EECON1, WR, 0); writeControl = false; startTime = 0; } } public 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 { 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 == 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 == EEADR) content &= 0b00111111; else if (address == EECON2) { if (content == 0x55) eecon2stages [0] = true; else if (content == 0xAA && eecon2stages[0]) eecon2stages [1] = true; else eecon2stages = new boolean[]{false, false}; } dataRegister.setDirectRegister(address, content); } break; } } private 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 && eecon2stages[0] && eecon2stages[1]) { 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); } @Override public void initialize(PICComponents picComponents) { super.initialize(picComponents); } }