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; import static fabrik.simulator.pic16f84.Commands.getTotalExecutionTime; 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; private static boolean [] eecon2stages = {false, false}; private static long startTime; 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; } registerTime(true); } public static void registerTime(boolean reset) { if (reset) startTime = getTotalExecutionTime(); else if ((getTotalExecutionTime() >= (startTime + 1)) && writeControl) { eecon2stages = new boolean[]{false, false}; DataRegister.setDirectBit(EECON1, EEIF, 1); DataRegister.setDirectBit(EECON1, WR, 0); writeControl = false; startTime = 0; } } 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 { 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 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 && 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); } }