implemented Stack (#10)

This commit is contained in:
DarkressX
2023-05-28 19:30:07 +02:00
committed by GitHub
parent 5c4aee2da6
commit 29ec2afe04
13 changed files with 103 additions and 33 deletions

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

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

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

View File

@@ -0,0 +1,6 @@
package de.darkress.pic16f84sim.commands;
public interface Command
{
void execute();
}

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

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

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

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

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

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

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

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