package fabrik.simulator.pic16f84; import fabrik.simulator.pic16f84.interfaces.*; public class Commands extends ExecutionTimeSubject implements CommandInterface { private int wRegister; private long totalExecutionTime; private double executionTimeMultiplier = 1; public Commands(){ super(); wRegister = 0; totalExecutionTime = 0; } public int get_wRegister() { return wRegister; } public void addExecutionTime(int i) { totalExecutionTime += i; super.notifyObservers(); } @Override public double getTotalExecutionTime() { return (totalExecutionTime * getExecutionTimeMultiplier()); } public void resetTotalExecutionTime() { totalExecutionTime = 0; super.notifyObservers(); } public void decode(int instruction){ 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; int k = instruction & constant; int b = (instruction & bitaddr) >> 7; int j = instruction & jumpaddr; switch (instruction & 0x3800){ case 0b10000000000000: System.out.println("CALL: " + j); CALL (j); addExecutionTime(2); return; case 0b10100000000000: System.out.println("GOTO: " + j); GOTO (j); addExecutionTime(2); return; default: break; } switch (instruction & 0x3C00){ case 0b01000000000000: System.out.println("BCF: " + f + " " + b); dataRegister.clearBit(f, b); addExecutionTime(1); return; case 0b01010000000000: System.out.println("BSF: " + f + " " + b); dataRegister.setBit(f, b); addExecutionTime(1); return; case 0b01100000000000: System.out.println("BTFSC: " + f + " " + b); BTFSC(f, b); addExecutionTime(1); return; case 0b01110000000000: System.out.println("BTFSS: " + f + " " + b); BTFSS(f, b); addExecutionTime(1); return; case 0b11000000000000: System.out.println("MOVLW: " + k); MOVLW (k); addExecutionTime(1); return; case 0b11010000000000: System.out.println("RETLW: " + k); RETLW (k); addExecutionTime(2); return; default: break; } switch (instruction & 0x3E00){ case 0b11111000000000: System.out.println("ADDLW: " + k); ADDLW (k); addExecutionTime(1); return; case 0b11110000000000: System.out.println("SUBLW: " + k); SUBLW (k); addExecutionTime(1); return; default: break; } switch (instruction & 0x3F00){ case 0b00011100000000: System.out.println("ADDWF: " + f + " " + d); ADDWF (f, d); addExecutionTime(1); return; case 0b00010100000000: System.out.println("ANDWF: " + f + " " + d); ANDWF (f, d); addExecutionTime(1); return; case 0b00100100000000: System.out.println("COMF: " + f + " " + d); COMF (f, d); addExecutionTime(1); return; case 0b00001100000000: System.out.println("DECF: " + f + " " + d); DECF (f, d); addExecutionTime(1); return; case 0b00101100000000: //1 bzw 2 Laufzeitpunkte System.out.println("DECFSZ: " + f + " " + d); DECFSZ (f, d); addExecutionTime(1); return; case 0b00101000000000: System.out.println("INCF: " + f + " " + d); INCF (f, d); addExecutionTime(1); return; case 0b00111100000000: System.out.println("INCFSZ: " + f + " " + d); INCFSZ (f, d); addExecutionTime(1); return; case 0b00010000000000: System.out.println("IORWF: " + f + " " + d); IORWF (f, d); addExecutionTime(1); return; case 0b00100000000000: System.out.println("MOVF: " + f + " " + d); MOVF (f, d); addExecutionTime(1); return; case 0b00110100000000: System.out.println("RLF: " + f + " " + d); RLF (f, d); addExecutionTime(1); return; case 0b00110000000000: System.out.println("RRF: " + f + " " + d); RRF (f, d); addExecutionTime(1); return; case 0b00001000000000: System.out.println("SUBWF: " + f + " " + d); SUBWF (f, d); addExecutionTime(1); return; case 0b00111000000000: System.out.println("SWAPF: " + f + " " + d); SWAPF (f, d); addExecutionTime(1); return; case 0b00011000000000: System.out.println("XORWF: " + f + " " + d); XORWF (f, d); addExecutionTime(1); return; case 0b11100100000000: System.out.println("ANDLW: " + k); ANDLW (k); addExecutionTime(1); return; case 0b11101000000000: System.out.println("XORLW: " + k); XORLW (k); addExecutionTime(1); return; case 0b11100000000000: System.out.println("IORLW: " + k); IORLW (k); addExecutionTime(1); return; default: break; } switch (instruction & 0x3F80){ case 0b00000110000000: System.out.println("CLRF: " + f); CLRF (f); addExecutionTime(1); return; case 0b00000100000000: System.out.println("CLRW"); CLRW (); addExecutionTime(1); return; case 0b00000010000000: System.out.println("MOVWF: " + f); MOVWF (f); addExecutionTime(1); return; default: break; } switch (instruction){ case 0b01100100: System.out.println("CLRWDT"); watchdogTimer.reset(); return; case 0b1001: System.out.println("RETFIE"); RETFIE(); addExecutionTime(2); return; case 0b1000: System.out.println("RETURN"); dataRegister.setPC(programStack.pop()); return; case 0b01100011: System.out.println("SLEEP"); SLEEP(); addExecutionTime(1); return; default: break; } if (instruction == 0 || instruction == 0b0110000 || instruction == 0b01000000 || instruction == 0b00100000){ NOP (); } else{ System.out.println("Nicht gefunden!"); } } public void SLEEP() { ExecutionState.sleep(); } public void RETFIE() { dataRegister.setBit(dataRegister.getINTCON(), 7); // GIE wieder setzen dataRegister.setPC(programStack.pop()); } public void NOP () { System.out.println("NOP"); addExecutionTime(1); } public void GOTO(int jump) { dataRegister.setPC(jump-1); } public void CALL(int jump) { programStack.push(dataRegister.getPC()+1); dataRegister.setPC(jump-1); addExecutionTime(1); } public void MOVWF(int file) { dataRegister.setRegister(file, wRegister); } public void CLRW() { wRegister = 0; dataRegister.determineZeroFlag(wRegister); addExecutionTime(1); } public void CLRF(int file) { dataRegister.setRegister(file, 0); dataRegister.determineZeroFlag(dataRegister.getRegister(file)); } public void IORLW(int literal) { wRegister |= literal; dataRegister.determineZeroFlag(wRegister); } public void XORLW(int literal) { wRegister ^= literal; dataRegister.determineZeroFlag(wRegister); } public void ANDLW(int literal) { wRegister &= literal; dataRegister.determineZeroFlag(wRegister); } public void XORWF(int file, int destination) { int result = wRegister ^ dataRegister.getRegister(file); if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } dataRegister.determineZeroFlag(result); } public void SWAPF(int file, int destination) { int content = dataRegister.getRegister(file); int result = (content & 0x0F) << 4 | (content & 0xF0) >> 4; if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } } public void SUBWF(int file, int destination) { int result = (dataRegister.getRegister(file) - wRegister) ; if (wRegister == 0 || result >= 0){ dataRegister.setCarryFlag(1); dataRegister.setDigitCarryFlag(1); } else { dataRegister.setCarryFlag(0); dataRegister.setDigitCarryFlag(0); } if (destination == 0){ wRegister = result & 0xFF; } else { dataRegister.setRegister(file, result & 0xFF); } dataRegister.determineZeroFlag(result); addExecutionTime(1); } public void RLF(int file, int destination) { 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 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 void MOVF(int file, int destination) { int content = dataRegister.getRegister(file); if (destination == 0){ wRegister = content; } else { dataRegister.setRegister(file, content); } dataRegister.determineZeroFlag(content); } public void IORWF(int file, int destination) { int result = wRegister | dataRegister.getRegister(file); if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } dataRegister.determineZeroFlag(result); } public void INCFSZ(int file, int destination) { int result = (dataRegister.getRegister(file) + 1) & 0xFF; if (destination == 0){ wRegister = result; addExecutionTime(1); } else { dataRegister.setRegister(file, result); } if (result == 0) { dataRegister.increasePC(); } } public void INCF(int file, int destination) { int result = (dataRegister.getRegister(file) + 1) & 0xFF; if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } dataRegister.determineZeroFlag(result); } public void DECFSZ(int file, int destination) { int result = (dataRegister.getRegister(file) -1) & 0xFF; if (destination == 0){ wRegister = result; addExecutionTime(1); } else { dataRegister.setRegister(file, result); } if (result == 0){ dataRegister.increasePC(); } } public void DECF(int file, int destination) { int result = (dataRegister.getRegister(file) -1) & 0xFF; if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } dataRegister.determineZeroFlag(result); } private void COMF(int file, int destination) { int result = (~ dataRegister.getRegister(file)) & 0xFF; if (destination == 0){ wRegister = result; } else { dataRegister.setRegister(file, result); } dataRegister.determineZeroFlag(result); } public void ANDWF(int file, int destination) { int result = wRegister & dataRegister.getRegister(file); if (destination == 0){ wRegister = result & 0xFF; } else { dataRegister.setRegister(file, result & 0xFF); } dataRegister.determineZeroFlag(result); dataRegister.determineCarryFlag(result); dataRegister.determineDigitCarryFlag((wRegister&0b11101111) & (dataRegister.getRegister(file)&0b1111)); } public void ADDWF(int file, int destination) { int result = wRegister + dataRegister.getRegister(file); if (wRegister == 0 || dataRegister.getRegister(file) == 0){ dataRegister.setCarryFlag(0); dataRegister.setDigitCarryFlag(0); } else { dataRegister.determineCarryFlag(result); dataRegister.determineDigitCarryFlag((wRegister&0b11101111) + (dataRegister.getRegister(file)&0b1111)); } if (destination == 0) { wRegister = result & 0xFF; } else { dataRegister.setRegister(file, result & 0xFF); } dataRegister.determineZeroFlag(result); } public void SUBLW(int literal) { 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 void ADDLW(int literal) { int result = wRegister + literal; wRegister = result & 0xFF; dataRegister.determineZeroFlag(result); dataRegister.determineCarryFlag(result); dataRegister.determineDigitCarryFlag((wRegister&0b11101111) + (literal&0b1111)); } public void RETLW(int literal) { wRegister = literal; dataRegister.setPC(programStack.pop()); } public void MOVLW(int literal) { wRegister = literal; } public void BTFSC(int address, int bit) { if (dataRegister.getBit(address, bit) == 0){ dataRegister.increasePC(); addExecutionTime(1); } } public void BTFSS(int address, int bit) { if (dataRegister.getBit(address, bit) == 1){ dataRegister.increasePC(); addExecutionTime(1); } } @Override public double getExecutionTimeMultiplier(){ return executionTimeMultiplier; } @Override public void setExecutionTimeMultiplier(String option){ switch (option) { case "8 MHZ": executionTimeMultiplier = 0.5; break; case "4 MHZ": executionTimeMultiplier = 1; break; case "1 MHZ": executionTimeMultiplier = 4; break; case "500 HZ": executionTimeMultiplier = 8; break; case "100 HZ": executionTimeMultiplier = 40; break; case "32 HZ": executionTimeMultiplier = 125; break; } super.notifyObservers(); } }