diff --git a/src/main/java/fabrik/simulator/pic16f84/Commands.java b/src/main/java/fabrik/simulator/pic16f84/Commands.java index b0e9c66..a0ef629 100644 --- a/src/main/java/fabrik/simulator/pic16f84/Commands.java +++ b/src/main/java/fabrik/simulator/pic16f84/Commands.java @@ -8,11 +8,11 @@ public class Commands { } public static void decode(int instruction){ - int jumpaddr = 0x7FF; - int fileregaddr = 0x7F; - int constant = 0xFF; - int bitaddr = 0x380; - int destinationbit = 0x80; + final int jumpaddr = 0x7FF; + final int fileregaddr = 0x7F; + final int constant = 0xFF; + final int bitaddr = 0x380; + final int destinationbit = 0x80; int d = (instruction & destinationbit) >> 7; int f = instruction & fileregaddr; @@ -116,6 +116,10 @@ public class Commands { System.out.println("RLF: " + f + " " + d); RLF (f, d); return; + case 0b00110000000000: + System.out.println("RRF: " + f + " " + d); + RRF (f, d); + return; case 0b00001000000000: System.out.println("SUBWF: " + f + " " + d); SUBWF (f, d); @@ -168,11 +172,11 @@ public class Commands { return; case 0b1001: System.out.println("RETFIE"); - //TODO + RETFIE(); return; case 0b1000: System.out.println("RETURN"); - //TODO + DataRegister.setPC(ProgramStack.pop()); return; case 0b01100011: System.out.println("SLEEP"); @@ -192,12 +196,17 @@ public class Commands { } + public static void RETFIE() { + DataRegister.setPC(ProgramStack.pop()); + } + public static void GOTO(int jump) { DataRegister.setPC(jump-1); } public static void CALL(int jump) { - //TODO + ProgramStack.push(DataRegister.getPC()+1); + DataRegister.setPC(jump-1); } public static void MOVWF(int file) { @@ -206,27 +215,27 @@ public class Commands { public static void CLRW() { wRegister = 0; - //TODO: Zeroflag + DataRegister.determineZeroFlag(wRegister); } public static void CLRF(int file) { DataRegister.setRegister(file, 0); - //TODO: Zeroflag + DataRegister.determineZeroFlag(DataRegister.getRegister(file)); } public static void IORLW(int literal) { wRegister |= literal; - //TODO: Zeroflag + DataRegister.determineZeroFlag(wRegister); } public static void XORLW(int literal) { wRegister ^= literal; - //TODO: Zeroflag + DataRegister.determineZeroFlag(wRegister); } public static void ANDLW(int literal) { wRegister &= literal; - //TODO: Zeroflag + DataRegister.determineZeroFlag(wRegister); } public static void XORWF(int file, int destination) { @@ -237,7 +246,7 @@ public class Commands { else { DataRegister.setRegister(file, result); } - //TODO: Zeroflag + DataRegister.determineZeroFlag(result); } public static void SWAPF(int file, int destination) { @@ -252,18 +261,49 @@ public class Commands { } public static void SUBWF(int file, int destination) { - int result = (DataRegister.getRegister(file) - wRegister) & 0xFF; - if (destination == 0){ - wRegister = result; + int result = (DataRegister.getRegister(file) - wRegister) ; + if (wRegister == 0 || result >= 0){ + DataRegister.setCarryFlag(1); + DataRegister.setDigitCarryFlag(1); } else { - DataRegister.setRegister(file, result); + DataRegister.setCarryFlag(0); + DataRegister.setDigitCarryFlag(0); } - // TODO Zeroflag, Carry, DigitCarry + if (destination == 0){ + wRegister = result & 0xFF; + } + else { + DataRegister.setRegister(file, result & 0xFF); + } + DataRegister.determineZeroFlag(result); } public static void RLF(int file, int destination) { - // TODO + int fcontent = DataRegister.getRegister(file); + int carry = DataRegister.getCarryFlag(); + int result = (fcontent << 1) | carry; + DataRegister.determineCarryFlag(result); + if (destination == 0){ + wRegister = result & 0xFF; + } + else { + DataRegister.setRegister(file, result & 0xFF); + } + } + + public static void RRF(int file, int destination) { + int fcontent = DataRegister.getRegister(file); + int carry = DataRegister.getCarryFlag() << 7; + int contentlow = fcontent & 0b1; + int result = fcontent >> 1 | carry; + DataRegister.setCarryFlag(contentlow); + if (destination == 0){ + wRegister = result & 0xFF; + } + else { + DataRegister.setRegister(file, result & 0xFF); + } } public static void MOVF(int file, int destination) { @@ -274,7 +314,7 @@ public class Commands { else { DataRegister.setRegister(file, content); } - // TODO: Zeroflag + DataRegister.determineZeroFlag(content); } public static void IORWF(int file, int destination) { @@ -285,7 +325,7 @@ public class Commands { else { DataRegister.setRegister(file, result); } - // TODO: Zeroflag + DataRegister.determineZeroFlag(result); } public static void INCFSZ(int file, int destination) { @@ -309,7 +349,7 @@ public class Commands { else { DataRegister.setRegister(file, result); } - //TODO: Zeroflag + DataRegister.determineZeroFlag(result); } public static void DECFSZ(int file, int destination) { @@ -333,7 +373,7 @@ public class Commands { else { DataRegister.setRegister(file, result); } - // TODO: Zeroflag + DataRegister.determineZeroFlag(result); } private static void COMF(int file, int destination) { @@ -344,44 +384,67 @@ public class Commands { else { DataRegister.setRegister(file, result); } - // TODO: Zeroflag + DataRegister.determineZeroFlag(result); } public static void ANDWF(int file, int destination) { int result = wRegister & DataRegister.getRegister(file); if (destination == 0){ - wRegister = result; + wRegister = result & 0xFF; } else { - DataRegister.setRegister(file, result); + DataRegister.setRegister(file, result & 0xFF); } - // TODO: Zeroflag, Carry, DigitCarry + DataRegister.determineZeroFlag(result); + DataRegister.determineCarryFlag(result); + DataRegister.determineDigitCarryFlag(result); } public static void ADDWF(int file, int destination) { int result = wRegister + DataRegister.getRegister(file); - if (destination == 0) { - wRegister = result; + if (wRegister == 0 || DataRegister.getRegister(file) == 0){ + DataRegister.setCarryFlag(0); + DataRegister.setDigitCarryFlag(0); } else { - DataRegister.setRegister(file, result); + DataRegister.determineCarryFlag(result); + DataRegister.determineDigitCarryFlag(result); } - // TODO: Zeroflag, Carry, DigitCarry + if (destination == 0) { + wRegister = result & 0xFF; + } + else { + DataRegister.setRegister(file, result & 0xFF); + } + DataRegister.determineZeroFlag(result); } public static void SUBLW(int literal) { - wRegister = literal - wRegister; - // TODO: Zeroflag, Carry, DigitCarry + int result = literal - wRegister; + if (wRegister == 0 || result >= 0){ + DataRegister.setCarryFlag(1); + DataRegister.setDigitCarryFlag(1); + } + else { + + DataRegister.setCarryFlag(0); + DataRegister.setDigitCarryFlag(0); + } + wRegister = result & 0xFF; + DataRegister.determineZeroFlag(result); } public static void ADDLW(int literal) { - wRegister += literal; - // TODO: Zeroflag, Carry, DigitCarry + int result = wRegister + literal; + wRegister = result & 0xFF; + DataRegister.determineZeroFlag(result); + DataRegister.determineCarryFlag(result); + DataRegister.determineDigitCarryFlag(result); } public static void RETLW(int literal) { wRegister = literal; - //TODO: PC vom Stack holen und laden + DataRegister.setPC(ProgramStack.pop()); } public static void MOVLW(int literal) { diff --git a/src/main/java/fabrik/simulator/pic16f84/Controller_FileSelect.java b/src/main/java/fabrik/simulator/pic16f84/Controller_FileSelect.java index eb9724f..6981b54 100644 --- a/src/main/java/fabrik/simulator/pic16f84/Controller_FileSelect.java +++ b/src/main/java/fabrik/simulator/pic16f84/Controller_FileSelect.java @@ -42,6 +42,9 @@ public class Controller_FileSelect { Commands.decode(prog[DataRegister.getPC()]); System.out.println("\nPC: " + DataRegister.getPC()); System.out.println("W: " + Commands.get_wRegister()); + System.out.println("C: " + DataRegister.getCarryFlag()); + System.out.println("DC: " + DataRegister.getDigitCarryFlag()); + System.out.println(ProgramStack.getStack()); System.out.printf(Arrays.toString(DataRegister.getDataRegister())); DataRegister.increasePC(); } diff --git a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java index 619a638..c01fbc9 100644 --- a/src/main/java/fabrik/simulator/pic16f84/DataRegister.java +++ b/src/main/java/fabrik/simulator/pic16f84/DataRegister.java @@ -3,30 +3,49 @@ package fabrik.simulator.pic16f84; import java.util.Arrays; public class DataRegister { - public static final int STATUS = 0x3; - public static final int TRISA = 0x85; - public static final int TRISB = 0x86; - public static final int PCL = 0x2; - public static final int RP0 = 0x5; + private static final int PCL = 0x2; + private static final int STATUS = 0x3; + private static final int FSR = 0x4; + private static final int PCLATH = 0xA; + private static final int INTCON = 0xB; + + private static final int TRISA = 0x85; + private static final int TRISB = 0x86; + + private static final int C = 0x0; + private static final int DC = 0x1; + private static final int Z = 0x2; + private static final int RP0 = 0x5; + private static final int [] dataRegister = new int[0xFF]; + private static final int [] syncedRegisters = {PCL, STATUS, FSR, PCLATH, INTCON}; public static void initDataRegister() { dataRegister[PCL] = 0b0; dataRegister[STATUS] = 0b00011000; - dataRegister[0xA] = 0b0; - dataRegister[0xB] = 0b0; + dataRegister[PCLATH] = 0b0; + dataRegister[INTCON] = 0b0; dataRegister[0x81] = 0b11111111; - dataRegister[0x82] = dataRegister[PCL]; - dataRegister[0x83] = dataRegister[STATUS]; + dataRegister[0x80 + PCL] = dataRegister[PCL]; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; dataRegister[TRISA] = 0b11111000; dataRegister[TRISB] = 0b11111111; - dataRegister[0x8A] = dataRegister[0xA]; - dataRegister[0x8B] = dataRegister[0xB]; + dataRegister[0x80 + PCLATH] = dataRegister[PCLATH]; + dataRegister[0x80 + INTCON] = dataRegister[INTCON]; System.out.println(Arrays.toString(dataRegister)); } + private static boolean isSyncedRegister (int address){ + for (int register : syncedRegisters){ + if (address == register || address == 0x80 + register){ + return true; + } + } + return false; + } + public static int[] getDataRegister() { return dataRegister; } @@ -40,22 +59,47 @@ public class DataRegister { } public static void setRegister(int fileAddress, int content){ - dataRegister[bank() + fileAddress] = content; + if (!isSyncedRegister(fileAddress)) + dataRegister[bank() + fileAddress] = content; + else { + dataRegister[fileAddress] = content; + dataRegister[0x80 + fileAddress] = content; + } } public static int getBit(int address, int bit) { return (dataRegister[bank() + address] >> bit) & 1; } + private static int getDirectBit(int address, int bit){ + return (dataRegister[address] >> bit) & 1; + } + public static void clearBit(int address, int bit) { - if (getBit(address, bit) == 1) { - dataRegister[bank() + address] -= (int) Math.pow(2, bit); + if (!isSyncedRegister(address)) { + if (getBit(address, bit) == 1) { + dataRegister[bank() + address] -= (int) Math.pow(2, bit); + } + } + else { + if (getBit(address, bit) == 1) { + dataRegister[address] -= (int) Math.pow(2, bit); + dataRegister[0x80 + address] = dataRegister[address]; + } } } public static void setBit(int address, int bit) { - if (getBit(address, bit) == 0) { - dataRegister[bank() + address] += (int) Math.pow(2, bit); + if (!isSyncedRegister(address)) { + if (getBit(address, bit) == 0) { + dataRegister[bank() + address] += (int) Math.pow(2, bit); + } + } + else { + if (getBit(address, bit) == 0) { + dataRegister[address] += (int) Math.pow(2, bit); + dataRegister[0x80 + address] = dataRegister[address]; + } } } @@ -85,4 +129,86 @@ public class DataRegister { public static int getPC(){ return programCounter; } + + private static int zeroFlag = 0; + + public static void determineZeroFlag(int result){ + if (result == 0){ + zeroFlag = 1; + if (getBit(STATUS, Z) == 0){ + dataRegister[STATUS] += 0b100; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + else { + zeroFlag = 0; + if (getBit(STATUS, Z) == 1){ + dataRegister[STATUS] -= 0b100; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + } + + private static int carryFlag = 0; + + public static void setCarryFlag(int value){ + carryFlag = value; + if (value == 1){ + if (getBit(STATUS, C) == 0){ + dataRegister[STATUS] += 0b1; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + else { + if (getBit(STATUS, C) == 1){ + dataRegister[STATUS] -= 0b1; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + } + + public static void determineCarryFlag (int result){ + if (result > 0xFF){ + setCarryFlag(1); + } + else { + setCarryFlag(0); + } + } + + public static int getCarryFlag (){ + return carryFlag; + } + + private static int digitCarryFlag = 0; + + public static void setDigitCarryFlag(int value){ + digitCarryFlag = value; + if (value == 1){ + if (getBit(STATUS, DC) == 0){ + dataRegister[STATUS] += 0b10; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + else { + if (getBit(STATUS, DC) == 1){ + dataRegister[STATUS] -= 0b10; + dataRegister[0x80 + STATUS] = dataRegister[STATUS]; + } + } + } + + public static void determineDigitCarryFlag(int result){ + if (result > 0xF){ + setDigitCarryFlag(1); + } + else { + setDigitCarryFlag(0); + } + } + + public static int getDigitCarryFlag(){ + return digitCarryFlag; + } + } diff --git a/src/main/java/fabrik/simulator/pic16f84/ProgramStack.java b/src/main/java/fabrik/simulator/pic16f84/ProgramStack.java new file mode 100644 index 0000000..2797ffa --- /dev/null +++ b/src/main/java/fabrik/simulator/pic16f84/ProgramStack.java @@ -0,0 +1,25 @@ +package fabrik.simulator.pic16f84; + +import java.util.ArrayDeque; +import java.util.Deque; + +public class ProgramStack { + private static Deque returnStack = new ArrayDeque<>(); + + public static void push(int value) { + if (returnStack.size() != 7) + returnStack.push(value); + else { + System.out.println("Stack overflow"); + } + + } + + public static int pop() { + return returnStack.pop(); + } + + public static Deque getStack() { + return returnStack; + } +}