RETURN, CALL + Stack

This commit is contained in:
2017-05-10 19:20:15 +02:00
parent 7b4a5ed4fe
commit b9dcf70dfe
4 changed files with 198 additions and 17 deletions

View File

@@ -113,7 +113,7 @@ namespace PIC_Simulator.PIC
public int Stepcount = 0;
public uint Register_W = 0;
public uint[] Register = new uint[0x100];
public Stack<uint> Stack = new Stack<uint>();
public PICProgramm()
{
@@ -203,6 +203,11 @@ namespace PIC_Simulator.PIC
if (aktueller_befehl.befehl == ADDWF)
{
// Add the contents of the W register with
// register 'f'.If 'd' is 0 the result is stored
// in the W register.If 'd' is 1 the result is
// stored back in register 'f'.
uint a = GetRegister(aktueller_befehl.parameter_f);
uint b = Register_W;
@@ -222,6 +227,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == ANDWF)
{
// AND the W register with register 'f'.If 'd'
// is 0 the result is stored in the W regis -
// ter.If 'd' is 1 the result is stored back in
// register 'f'
uint Result = Register_W & GetRegister(aktueller_befehl.parameter_f);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -233,16 +243,27 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == CLRF)
{
// The contents of register 'f' are cleared
// and the Z bit is set.
SetRegister(aktueller_befehl.parameter_f, 0x00);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, true);
}
else if (aktueller_befehl.befehl == CLRW)
{
Register_W = 0;
// W register is cleared.Zero bit (Z) is
// set.
Register_W = 0;
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, true);
}
else if (aktueller_befehl.befehl == COMF)
{
// The contents of register 'f' are comple-
// mented.If 'd' is 0 the result is stored in
// W.If 'd' is 1 the result is stored back in
// register 'f'.
uint Result = ~GetRegister(aktueller_befehl.parameter_f);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -254,6 +275,10 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == DECF)
{
// Decrement register 'f'.If 'd' is 0 the
// result is stored in the W register.If 'd' is
// 1 the result is stored back in register 'f'.
uint Result = GetRegister(aktueller_befehl.parameter_f);
if (Result == 0)
@@ -270,6 +295,15 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == DECFSZ)
{
// The contents of register 'f' are decre-
// mented.If 'd' is 0 the result is placed in the
// W register.If 'd' is 1 the result is placed
// back in register 'f'.
// If the result is 1, the next instruction, is
// executed.If the result is 0, then a NOP is
// executed instead making it a 2T CY instruc -
// tion.
bool Cond = GetRegister(aktueller_befehl.parameter_f) == 1;
uint Result = GetRegister(aktueller_befehl.parameter_f);
@@ -291,6 +325,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == INCF)
{
// The contents of register 'f' are incre-
// mented.If 'd' is 0 the result is placed in
// the W register.If 'd' is 1 the result is
// placed back in register 'f'.
uint Result = GetRegister(aktueller_befehl.parameter_f);
Result += 1;
@@ -306,6 +345,15 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == INCFSZ)
{
// The contents of register 'f' are incre-
// mented.If 'd' is 0 the result is placed in
// the W register.If 'd' is 1 the result is
// placed back in register 'f'.
// If the result is 1, the next instruction is
// executed.If the result is 0, a NOP is exe -
// cuted instead making it a 2T CY instruc -
// tion
bool Cond = GetRegister(aktueller_befehl.parameter_f) == 0xFF;
uint Result = GetRegister(aktueller_befehl.parameter_f);
@@ -326,6 +374,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == IORWF)
{
// Inclusive OR the W register with regis -
// ter 'f'.If 'd' is 0 the result is placed in the
// W register.If 'd' is 1 the result is placed
// back in register 'f'.
uint Result = Register_W | GetRegister(aktueller_befehl.parameter_f);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -337,6 +390,13 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == MOVF)
{
// The contents of register f is moved to a
// destination dependant upon the status
// of d. If d = 0, destination is W register. If
// d = 1, the destination is file register f
// itself.d = 1 is useful to test a file regis-
// ter since status flag Z is affected.
uint Result = GetRegister(aktueller_befehl.parameter_f);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -348,14 +408,23 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == MOVWF)
{
// Move data from W register to register
// 'f'
SetRegister(aktueller_befehl.parameter_f, Register_W);
}
else if (aktueller_befehl.befehl == NOP)
{
// ~~~~~
//No operation.
}
else if (aktueller_befehl.befehl == RLF)
{
// The contents of register 'f' are rotated
// one bit to the left through the Carry
// Flag.If 'd' is 0 the result is placed in the
// W register.If 'd' is 1 the result is stored
// back in register 'f'.
uint Result = GetRegister(aktueller_befehl.parameter_f);
uint Carry_Old = GetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C) ? 1u : 0u;
@@ -375,6 +444,12 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == RRF)
{
// The contents of register 'f' are rotated
// one bit to the right through the Carry
// Flag.If 'd' is 0 the result is placed in the
// W register.If 'd' is 1 the result is placed
// back in register 'f'.
uint Result = GetRegister(aktueller_befehl.parameter_f);
uint Carry_Old = GetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_C) ? 0x80u : 0x00u;
@@ -394,6 +469,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == SUBWF)
{
// Subtract(2s complement method) W reg-
// ister from register 'f'.If 'd' is 0 the result is
// stored in the W register.If 'd' is 1 the
// result is stored back in register 'f'.
uint a = GetRegister(aktueller_befehl.parameter_f);
uint b = Register_W;
@@ -421,6 +501,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == SWAPF)
{
// The upper and lower nibbles of register
// 'f' are exchanged. If 'd' is 0 the result is
// placed in W register. If 'd' is 1 the result
// is placed in register 'f'.
uint Result = GetRegister(aktueller_befehl.parameter_f);
uint Low = Result & 0x0F;
@@ -435,6 +520,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == XORWF)
{
// Exclusive OR the contents of the W
// register with register 'f'.If 'd' is 0 the
// result is stored in the W register.If 'd' is
// 1 the result is stored back in register 'f'.
uint Result = Register_W ^ GetRegister(aktueller_befehl.parameter_f);
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -446,14 +536,25 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == BCF)
{
// Bit 'b' in register 'f' is cleared
SetRegister(aktueller_befehl.parameter_f, aktueller_befehl.parameter_b, false);
}
else if (aktueller_befehl.befehl == BSF)
{
// Bit 'b' in register 'f' is set.
SetRegister(aktueller_befehl.parameter_f, aktueller_befehl.parameter_b, true);
}
else if (aktueller_befehl.befehl == BTFSC)
{
// If bit 'b' in register 'f' is '1' then the next
// instruction is executed.
// If bit 'b', in register 'f', is '0' then the next
// instruction is discarded, and a NOP is
// executed instead, making this a 2T CY
// instruction
if (!GetBit(GetRegister(aktueller_befehl.parameter_f), aktueller_befehl.parameter_b))
{
PCCounter++;
@@ -461,6 +562,12 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == BTFSS)
{
// If bit 'b' in register 'f' is '0' then the next
// instruction is executed.
// If bit 'b' is '1', then the next instruction is
// discarded and a NOP is executed
// instead, making this a 2T CY instruction.
if (GetBit(GetRegister(aktueller_befehl.parameter_f), aktueller_befehl.parameter_b))
{
PCCounter++;
@@ -468,6 +575,10 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == ADDLW)
{
// The contents of the W register are
// added to the eight bit literal 'k' and the
// result is placed in the W register
uint a = Register_W;
uint b = aktueller_befehl.parameter_k;
@@ -484,6 +595,10 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == ANDLW)
{
// The contents of W register are
// ANDed with the eight bit literal 'k'.The
// result is placed in the W register
uint Result = Register_W & aktueller_befehl.parameter_k;
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -492,18 +607,41 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == CALL)
{
//TODO
// Call Subroutine. First, return address
// (PC + 1) is pushed onto the stack. The
// eleven bit immediate address is loaded
// into PC bits<10:0 >.The upper bits of
// the PC are loaded from PCLATH.CALL
// is a two cycle instruction.
Stack.Push((uint) PCCounter);
PCCounter = (int) (aktueller_befehl.parameter_k - 1);
}
else if (aktueller_befehl.befehl == CLRWDT)
{
// CLRWDT instruction resets the Watch -
// dog Timer.It also resets the prescaler
// of the WDT. Status bits TO and PD are
// set.
//TODO
}
else if (aktueller_befehl.befehl == GOTO)
{
// GOTO is an unconditional branch.The
// eleven bit immediate value is loaded
// into PC bits<10:0>.The upper bits of
// PC are loaded from PCLATH<4:3>.
// GOTO is a two cycle instruction.
PCCounter = befehle.FindIndex(b => b.labelnummer == aktueller_befehl.parameter_k) - 1;
}
else if (aktueller_befehl.befehl == IORLW)
{
// The contents of the W register is
// ORed with the eight bit literal 'k'.The
// result is placed in the W register
uint Result = Register_W | aktueller_befehl.parameter_k;
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);
@@ -512,26 +650,59 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == MOVLW)
{
// The eight bit literal 'k' is loaded into W
// register.The dont cares will assemble
// as 0s.
Register_W = aktueller_befehl.parameter_k;
}
else if (aktueller_befehl.befehl == RETFIE)
{
// Return from Interrupt.Stack is POPed
// and Top of Stack(TOS) is loaded in the
// PC.Interrupts are enabled by setting
// Global Interrupt Enable bit, GIE
// (INTCON < 7 >).This is a two cycle
// instruction.
//TODO
}
else if (aktueller_befehl.befehl == RETLW)
{
//TODO
// The W register is loaded with the eight
// bit literal 'k'.The program counter is
// loaded from the top of the stack(the
// return address). This is a two cycle
// instruction.
Register_W = aktueller_befehl.parameter_k;
PCCounter = (int) Stack.Pop();
}
else if (aktueller_befehl.befehl == RETURN)
{
//TODO
// Return from subroutine. The stack is
// POPed and the top of the stack(TOS)
// is loaded into the program counter.This
// is a two cycle instruction.
PCCounter = (int)Stack.Pop();
}
else if (aktueller_befehl.befehl == SLEEP)
{
// The power-down status bit, PD is
// cleared.Time -out status bit, TO is
// set.Watchdog Timer and its prescaler
// are cleared.
// The processor is put into SLEEP
// mode with the oscillator stopped. See
// Section 14.8 for more details.
//TODO
}
else if (aktueller_befehl.befehl == SUBLW)
{
// The W register is subtracted (2s comple-
// ment method) from the eight bit literal 'k'.
// The result is placed in the W register.
uint a = aktueller_befehl.parameter_k;
uint b = Register_W;
@@ -556,6 +727,11 @@ namespace PIC_Simulator.PIC
}
else if (aktueller_befehl.befehl == XORLW)
{
// The contents of the W register are
// XORed with the eight bit literal 'k'.
// The result is placed in the W regis -
// ter.
uint Result = Register_W ^ aktueller_befehl.parameter_k;
SetRegisterOhneBank(ADDR_STATUS, STATUS_BIT_Z, Result == 0);