implemented Stack (#10)
This commit is contained in:
33
de/darkress/pic16f84sim/Main.java
Normal file
33
de/darkress/pic16f84sim/Main.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package de.darkress.pic16f84sim;
|
||||
|
||||
import de.darkress.pic16f84sim.commands.Command;
|
||||
import de.darkress.pic16f84sim.decoder.CommandDecoder;
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
import de.darkress.pic16f84sim.registers.Stack;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class Main
|
||||
{
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
ArrayList<Command> program = new ArrayList<>();
|
||||
int input1 = 0x3EFF;
|
||||
program.add(CommandDecoder.decode(input1));
|
||||
program.get(0).execute();
|
||||
*/
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
Stack.push(i);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 16; i++)
|
||||
{
|
||||
System.out.println(Stack.peek());
|
||||
Stack.pop();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
25
de/darkress/pic16f84sim/commands/Addlw.java
Normal file
25
de/darkress/pic16f84sim/commands/Addlw.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class Addlw extends CommandUtils implements Command
|
||||
{
|
||||
private final int literal;
|
||||
|
||||
public Addlw(int input)
|
||||
{
|
||||
literal = input & 0x00FF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
int result = literal + Memory.workingRegister;
|
||||
|
||||
checkZeroBit(result);
|
||||
checkCarryBit(result);
|
||||
checkDigitCarryBit(literal);
|
||||
|
||||
Memory.workingRegister = result % 256;
|
||||
}
|
||||
}
|
||||
22
de/darkress/pic16f84sim/commands/Andlw.java
Normal file
22
de/darkress/pic16f84sim/commands/Andlw.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class Andlw extends CommandUtils implements Command
|
||||
{
|
||||
private final int literal;
|
||||
|
||||
public Andlw(int input)
|
||||
{
|
||||
literal = input & 0x00FF;
|
||||
}
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
int result = literal & Memory.workingRegister;
|
||||
|
||||
checkZeroBit(result);
|
||||
|
||||
Memory.workingRegister = result % 256;
|
||||
}
|
||||
}
|
||||
6
de/darkress/pic16f84sim/commands/Command.java
Normal file
6
de/darkress/pic16f84sim/commands/Command.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
public interface Command
|
||||
{
|
||||
void execute();
|
||||
}
|
||||
33
de/darkress/pic16f84sim/commands/CommandUtils.java
Normal file
33
de/darkress/pic16f84sim/commands/CommandUtils.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class CommandUtils
|
||||
{
|
||||
protected void checkZeroBit(int result)
|
||||
{
|
||||
if((result % 256) == 0){
|
||||
Memory.setZeroBit();
|
||||
} else{
|
||||
Memory.clearZeroBit();
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkCarryBit(int result)
|
||||
{
|
||||
if(result > 255){
|
||||
Memory.setCarryBit();
|
||||
} else{
|
||||
Memory.clearCarryBit();
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkDigitCarryBit(int literal)
|
||||
{
|
||||
if(((Memory.workingRegister & 0x0F) + (literal & 0x0F)) > 15){
|
||||
Memory.setDigitCarryBit();
|
||||
} else{
|
||||
Memory.clearDigitCarryBit();
|
||||
}
|
||||
}
|
||||
}
|
||||
22
de/darkress/pic16f84sim/commands/Iorlw.java
Normal file
22
de/darkress/pic16f84sim/commands/Iorlw.java
Normal file
@@ -0,0 +1,22 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class Iorlw extends CommandUtils implements Command
|
||||
{
|
||||
private final int literal;
|
||||
|
||||
public Iorlw(int input)
|
||||
{
|
||||
literal = input & 0x00FF;
|
||||
}
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
int result = literal | Memory.workingRegister;
|
||||
|
||||
checkZeroBit(result);
|
||||
|
||||
Memory.workingRegister = result % 256;
|
||||
}
|
||||
}
|
||||
19
de/darkress/pic16f84sim/commands/Movlw.java
Normal file
19
de/darkress/pic16f84sim/commands/Movlw.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class Movlw extends CommandUtils implements Command
|
||||
{
|
||||
private final int literal;
|
||||
|
||||
public Movlw(int input)
|
||||
{
|
||||
literal = input & 0x00FF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
Memory.workingRegister = literal;
|
||||
}
|
||||
}
|
||||
45
de/darkress/pic16f84sim/commands/Sublw.java
Normal file
45
de/darkress/pic16f84sim/commands/Sublw.java
Normal file
@@ -0,0 +1,45 @@
|
||||
package de.darkress.pic16f84sim.commands;
|
||||
|
||||
import de.darkress.pic16f84sim.registers.Memory;
|
||||
|
||||
public class Sublw extends CommandUtils implements Command
|
||||
{
|
||||
private final int literal;
|
||||
|
||||
public Sublw(int input)
|
||||
{
|
||||
literal = input & 0x00FF;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkCarryBit(int result)
|
||||
{
|
||||
if(result <= 255){
|
||||
Memory.clearCarryBit();
|
||||
} else{
|
||||
Memory.setCarryBit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void checkDigitCarryBit(int literal)
|
||||
{
|
||||
if(((literal & 0x0F) - (Memory.workingRegister & 0x0F)) < 0){
|
||||
Memory.clearDigitCarryBit();
|
||||
} else{
|
||||
Memory.setDigitCarryBit();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute()
|
||||
{
|
||||
int result = literal - Memory.workingRegister + 256;
|
||||
|
||||
checkZeroBit(result);
|
||||
checkCarryBit(result);
|
||||
checkDigitCarryBit(literal);
|
||||
|
||||
Memory.workingRegister = result % 256;
|
||||
}
|
||||
}
|
||||
149
de/darkress/pic16f84sim/decoder/CommandDecoder.java
Normal file
149
de/darkress/pic16f84sim/decoder/CommandDecoder.java
Normal file
@@ -0,0 +1,149 @@
|
||||
package de.darkress.pic16f84sim.decoder;
|
||||
|
||||
import de.darkress.pic16f84sim.commands.*;
|
||||
|
||||
public class CommandDecoder
|
||||
{
|
||||
public static Command decode(int input)
|
||||
{
|
||||
switch(input & 0x3F00)
|
||||
{
|
||||
case 0x700:
|
||||
//addwf();
|
||||
break;
|
||||
case 0x500:
|
||||
//andwf();
|
||||
break;
|
||||
case 0x900:
|
||||
//comf();
|
||||
break;
|
||||
case 0x300:
|
||||
//decf();
|
||||
break;
|
||||
case 0xB00:
|
||||
//decfsz();
|
||||
break;
|
||||
case 0xA00:
|
||||
//incf();
|
||||
break;
|
||||
case 0xF00:
|
||||
//incfsz();
|
||||
break;
|
||||
case 0x400:
|
||||
//iorwf();
|
||||
break;
|
||||
case 0x800:
|
||||
//movf();
|
||||
break;
|
||||
case 0xD00:
|
||||
//rlf();
|
||||
break;
|
||||
case 0xC00:
|
||||
//rrf();
|
||||
break;
|
||||
case 0x200:
|
||||
//subwf();
|
||||
break;
|
||||
case 0xE00:
|
||||
//swapf();
|
||||
break;
|
||||
case 0x600:
|
||||
//xorwf();
|
||||
break;
|
||||
case 0x3900:
|
||||
return new Andlw(input);
|
||||
case 0x3800:
|
||||
return new Iorlw(input);
|
||||
case 0x3A00:
|
||||
//xorlw();
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input & 0x3F80)
|
||||
{
|
||||
case 0x180:
|
||||
//clrf();
|
||||
break;
|
||||
case 0x100:
|
||||
//clrw();
|
||||
break;
|
||||
case 0x80:
|
||||
//movwf();
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input & 0x3C00)
|
||||
{
|
||||
case 0x1000:
|
||||
//bcf();
|
||||
break;
|
||||
case 0x1400:
|
||||
//bsf();
|
||||
break;
|
||||
case 0x1800:
|
||||
//btfsc();
|
||||
break;
|
||||
case 0x1C00:
|
||||
//btfss();
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input & 0x3E00)
|
||||
{
|
||||
case 0x3E00:
|
||||
//addlw();
|
||||
return new Addlw(input);
|
||||
//break;
|
||||
case 0x3C00:
|
||||
return new Sublw(input);
|
||||
}
|
||||
|
||||
switch(input & 0x3800)
|
||||
{
|
||||
case 0x2000:
|
||||
//call();
|
||||
break;
|
||||
case 0x2800:
|
||||
//goto();
|
||||
break;
|
||||
}
|
||||
|
||||
switch(input & 0x3C00)
|
||||
{
|
||||
case 0x3000:
|
||||
return new Movlw(input);
|
||||
case 0x3400:
|
||||
//retlw();
|
||||
break;
|
||||
}
|
||||
|
||||
if ((input | 0x0060) == 0x0060)
|
||||
{
|
||||
//nop();
|
||||
}
|
||||
|
||||
if (input == 0x0064)
|
||||
{
|
||||
//clrwdt();
|
||||
}
|
||||
|
||||
if (input == 0x0009)
|
||||
{
|
||||
//retfie();
|
||||
}
|
||||
|
||||
if (input == 0x0008)
|
||||
{
|
||||
//return();
|
||||
//This is the function name. Do not mistake this for a normal return!
|
||||
}
|
||||
|
||||
if (input == 0x0063)
|
||||
{
|
||||
//sleep();
|
||||
}
|
||||
|
||||
System.out.println("No command matched");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
33
de/darkress/pic16f84sim/parser/Parser.java
Normal file
33
de/darkress/pic16f84sim/parser/Parser.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package de.darkress.pic16f84sim.parser;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
|
||||
public class Parser
|
||||
{
|
||||
public static List<Integer> parser(String filePath)
|
||||
{
|
||||
ArrayList<Integer> program = new ArrayList<>();
|
||||
try {
|
||||
File file = new File(filePath);
|
||||
Scanner scanner = new Scanner(file);
|
||||
while (scanner.hasNextLine()) {
|
||||
String data = scanner.nextLine();
|
||||
if(!data.startsWith(" "))
|
||||
{
|
||||
String commandAndParametersString = "0x" + data.split(" ")[1];
|
||||
int commandAndParameters = Integer.decode(commandAndParametersString);
|
||||
program.add(commandAndParameters);
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.println("An error occurred.");
|
||||
e.printStackTrace();
|
||||
}
|
||||
return program;
|
||||
}
|
||||
}
|
||||
138
de/darkress/pic16f84sim/registers/Memory.java
Normal file
138
de/darkress/pic16f84sim/registers/Memory.java
Normal file
@@ -0,0 +1,138 @@
|
||||
package de.darkress.pic16f84sim.registers;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Memory
|
||||
{
|
||||
private static final int MEMORY_SIZE = 0xFF; //Addressable Memory
|
||||
public static int workingRegister = 0;
|
||||
private static final int[] memory = new int[MEMORY_SIZE];
|
||||
private static final int[] bank0UniqueSpecialRegister = new int[] {0x01,0x05,0x06,0x08,0x09}; //and many more
|
||||
private static final int[] bank1UniqueSpecialRegister = new int[] {0x81,0x85,0x86,0x88,0x89}; //and many more
|
||||
|
||||
public static int getRegister(int address)
|
||||
{
|
||||
if(address + 128 > 255) //Guard statement to check for early errors in command de.darkress.pic16f84sim.decoder or implementation
|
||||
{
|
||||
System.err.println("Guard statement triggered. The address must be 7Bit long and can therefore not exceed" +
|
||||
" 127");
|
||||
System.exit(1);
|
||||
}
|
||||
if(address == 0x0)
|
||||
{
|
||||
int indirectAddress = getFSR();
|
||||
return getDataFromIndirectAddress(indirectAddress);
|
||||
}
|
||||
if(getRegisterBank() != 0)
|
||||
{
|
||||
if((Arrays.stream(bank1UniqueSpecialRegister).anyMatch(x -> x == address))) //Check if register ist mapped
|
||||
{
|
||||
return memory[address + 128]; //Ensure data is read from bank 1
|
||||
}
|
||||
}
|
||||
return memory[address];
|
||||
}
|
||||
|
||||
public static void setRegister(int address, int data)
|
||||
{
|
||||
if(address + 128 > 255) //Guard statement to check for early errors in command de.darkress.pic16f84sim.decoder or implementation
|
||||
{
|
||||
System.err.println("Guard statement triggered. The address must be 7Bit long and can therefore not exceed" +
|
||||
" 127");
|
||||
System.exit(1);
|
||||
}
|
||||
if(address == 0x0)
|
||||
{
|
||||
int indirectAddress = getFSR();
|
||||
setDataFromIndirectAddress(indirectAddress, data);
|
||||
return;
|
||||
}
|
||||
if((Arrays.stream(bank0UniqueSpecialRegister).anyMatch(x -> x == address)) && getRegisterBank() == 0)
|
||||
{
|
||||
memory[address] = data;
|
||||
return;
|
||||
}
|
||||
if((Arrays.stream(bank1UniqueSpecialRegister).anyMatch(x -> x == address)) && getRegisterBank() == 1)
|
||||
{
|
||||
memory[address + 128] = data;
|
||||
return;
|
||||
}
|
||||
memory[address] = data;
|
||||
memory[address + 128] = data; //Ensure data is written to both banks to simulate mapping
|
||||
}
|
||||
|
||||
private static int getDataFromIndirectAddress(int address)
|
||||
{
|
||||
return memory[address];
|
||||
}
|
||||
|
||||
private static void setDataFromIndirectAddress(int address, int data)
|
||||
{
|
||||
if((Arrays.stream(bank0UniqueSpecialRegister).anyMatch(x -> x == address)) || (Arrays.stream(bank1UniqueSpecialRegister).anyMatch(x -> x == address)))
|
||||
{
|
||||
memory[address] = data;
|
||||
return;
|
||||
}
|
||||
memory[address % 128] = data; // else: Registers.Registers which are mapped
|
||||
memory[address % 128 + 128] = data; //Ensure data is written to both banks to simulate mapping
|
||||
}
|
||||
|
||||
private static int getRegisterBank()
|
||||
{
|
||||
if((memory[0x03] & 0x20) == 0x0) //Check RP0 Bit of Bank0 Status Register
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private static int getFSR()
|
||||
{
|
||||
return memory[0x4];
|
||||
}
|
||||
|
||||
public static boolean getZeroBit()
|
||||
{
|
||||
return (memory[0x03] & 0x04) == 0x04;
|
||||
}
|
||||
|
||||
public static void setZeroBit()
|
||||
{
|
||||
memory[0x03] |= 0x04;
|
||||
}
|
||||
|
||||
public static void clearZeroBit()
|
||||
{
|
||||
memory[0x03] &= 0xFB;
|
||||
}
|
||||
|
||||
public static boolean getDigitCarryBit()
|
||||
{
|
||||
return (memory[0x03] & 0x02) == 0x02;
|
||||
}
|
||||
|
||||
public static void setDigitCarryBit()
|
||||
{
|
||||
memory[0x03] |= 0x02;
|
||||
}
|
||||
|
||||
public static void clearDigitCarryBit()
|
||||
{
|
||||
memory[0x03] &= 0xFD;
|
||||
}
|
||||
|
||||
public static boolean getCarryBit()
|
||||
{
|
||||
return (memory[0x03] & 0x01) == 0x01;
|
||||
}
|
||||
|
||||
public static void setCarryBit()
|
||||
{
|
||||
memory[0x03] |= 0x01;
|
||||
}
|
||||
|
||||
public static void clearCarryBit()
|
||||
{
|
||||
memory[0x03] &= 0xFE;
|
||||
}
|
||||
}
|
||||
51
de/darkress/pic16f84sim/registers/Stack.java
Normal file
51
de/darkress/pic16f84sim/registers/Stack.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package de.darkress.pic16f84sim.registers;
|
||||
|
||||
|
||||
public class Stack
|
||||
{
|
||||
private static int[] stack = new int[8];
|
||||
private static int stackPointer = 0;
|
||||
|
||||
public static void push(int data)
|
||||
{
|
||||
stack[stackPointer] = data;
|
||||
pointNext();
|
||||
}
|
||||
|
||||
public static int pop()
|
||||
{
|
||||
int tmp = stack[stackPointer];
|
||||
pointPrevious();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
public static int peek()
|
||||
{
|
||||
return stack[(stackPointer + 7) % 8]; //Get TopOfStack -1 +8 = 7 and modulo 8 to avoid IndexOutOfBound
|
||||
}
|
||||
|
||||
private static void pointNext()
|
||||
{
|
||||
if(stackPointer == 7)
|
||||
{
|
||||
stackPointer = 0;
|
||||
return;
|
||||
}
|
||||
stackPointer++;
|
||||
}
|
||||
|
||||
private static void pointPrevious()
|
||||
{
|
||||
if(stackPointer == 0)
|
||||
{
|
||||
stackPointer = 7;
|
||||
return;
|
||||
}
|
||||
stackPointer--;
|
||||
}
|
||||
|
||||
public static int getStackPointer()
|
||||
{
|
||||
return stackPointer;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user