Files
PIC-Simu/src/main/java/fabrik/simulator/pic16f84/EEPROM.java
2025-04-25 15:18:36 +02:00

180 lines
6.2 KiB
Java

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);
}
}