diff --git a/PIC_Simulator/Form1.Designer.cs b/PIC_Simulator/Form1.Designer.cs
index 199c613..8c9d6fd 100644
--- a/PIC_Simulator/Form1.Designer.cs
+++ b/PIC_Simulator/Form1.Designer.cs
@@ -28,7 +28,6 @@
///
private void InitializeComponent()
{
- this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.box_CodeView = new System.Windows.Forms.RichTextBox();
this.lbl_path = new System.Windows.Forms.Label();
@@ -44,7 +43,6 @@
this.hilfeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.cmdOpenDoc = new System.Windows.Forms.ToolStripMenuItem();
this.label4 = new System.Windows.Forms.Label();
- this.timer1 = new System.Windows.Forms.Timer(this.components);
this.lvMemory = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
@@ -60,6 +58,7 @@
this.lvSpecial = new System.Windows.Forms.ListView();
this.c1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.c2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
+ this.lbStack = new System.Windows.Forms.ListBox();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
@@ -201,10 +200,6 @@
this.label4.TabIndex = 10;
this.label4.Text = "Quarzfrequenz in s";
//
- // timer1
- //
- this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
- //
// lvMemory
//
this.lvMemory.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
@@ -317,11 +312,20 @@
this.c2.Text = "Wert";
this.c2.Width = 128;
//
+ // lbStack
+ //
+ this.lbStack.FormattingEnabled = true;
+ this.lbStack.Location = new System.Drawing.Point(640, 78);
+ this.lbStack.Name = "lbStack";
+ this.lbStack.Size = new System.Drawing.Size(88, 290);
+ this.lbStack.TabIndex = 19;
+ //
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1048, 585);
+ this.Controls.Add(this.lbStack);
this.Controls.Add(this.lvSpecial);
this.Controls.Add(this.insertTime);
this.Controls.Add(this.lbl_Timer);
@@ -364,7 +368,6 @@
private System.Windows.Forms.ToolStripMenuItem hilfeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem cmdOpenDoc;
private System.Windows.Forms.Label label4;
- private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.ListView lvMemory;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
@@ -381,6 +384,7 @@
private System.Windows.Forms.ListView lvSpecial;
private System.Windows.Forms.ColumnHeader c1;
private System.Windows.Forms.ColumnHeader c2;
- }
+ private System.Windows.Forms.ListBox lbStack;
+ }
}
diff --git a/PIC_Simulator/Form1.cs b/PIC_Simulator/Form1.cs
index b7a62f0..2587a6c 100644
--- a/PIC_Simulator/Form1.cs
+++ b/PIC_Simulator/Form1.cs
@@ -3,6 +3,7 @@ using PIC_Simulator.Properties;
using System;
using System.Drawing;
using System.IO;
+using System.Linq;
using System.Windows.Forms;
namespace PIC_Simulator
@@ -160,6 +161,9 @@ namespace PIC_Simulator
lvSpecial.Items[1].SubItems[1].Text = string.Format("{0,4}", programm.PCCounter);
lvSpecial.Items[2].SubItems[1].Text = string.Format("0b{0}", Convert.ToString(programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS), 2).PadLeft(8, '0'));
lvSpecial.Items[1].SubItems[1].Text = string.Format("{0}ms", programm.Stepcount * int.Parse(insertTime.Text));
+
+ lbStack.Items.Clear();
+ foreach (var u in programm.Stack) lbStack.Items.Add(u.ToString());
}
}
}
diff --git a/PIC_Simulator/Form1.resx b/PIC_Simulator/Form1.resx
index 965c506..d81e37a 100644
--- a/PIC_Simulator/Form1.resx
+++ b/PIC_Simulator/Form1.resx
@@ -126,7 +126,4 @@
211, 17
-
- 367, 17
-
\ No newline at end of file
diff --git a/PIC_Simulator/PIC/PICProgramm.cs b/PIC_Simulator/PIC/PICProgramm.cs
index fa6e579..0951d80 100644
--- a/PIC_Simulator/PIC/PICProgramm.cs
+++ b/PIC_Simulator/PIC/PICProgramm.cs
@@ -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 Stack = new Stack();
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(2’s 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
+ // AND’ed 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
+ // OR’ed 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 don’t cares will assemble
+ // as 0’s.
+
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 (2’s 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
+ // XOR’ed 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);