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);