180 lines
6.2 KiB
Java
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);
|
|
}
|
|
}
|