Timer (~)

This commit is contained in:
Mike Schwörer 2017-05-16 09:35:47 +02:00
parent 7ebfa04f5d
commit d62ff92a20
3 changed files with 152 additions and 31 deletions

View File

@ -33,6 +33,7 @@ namespace PIC_Simulator
lvSpecial.Items.Add(new ListViewItem(new[] { "W", "0x00" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "PC", "0x00" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "Status", "0b00000000" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "Option", "0b00000000" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "Time", "0ms" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "RA (Backing)", "0b00000000" }));
lvSpecial.Items.Add(new ListViewItem(new[] { "RB (Backing)", "0b00000000" }));
@ -196,12 +197,13 @@ namespace PIC_Simulator
lvSpecial.Items[0].SubItems[1].Text = string.Format("0x{0:X2}", programm.Register_W);
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[3].SubItems[1].Text = string.Format("{0}ms", programm.Stepcount * int.Parse(insertTime.Text));
lvSpecial.Items[4].SubItems[1].Text = "0b" + Convert.ToString(programm.Register[PICProgramm.ADDR_PORT_A], 2).PadLeft(8, '0');
lvSpecial.Items[5].SubItems[1].Text = "0b" + Convert.ToString(programm.Register[PICProgramm.ADDR_PORT_B], 2).PadLeft(8, '0');
lvSpecial.Items[6].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_C) ? "1" : "0";
lvSpecial.Items[7].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_DC) ? "1" : "0";
lvSpecial.Items[8].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_Z) ? "1" : "0";
lvSpecial.Items[3].SubItems[1].Text = string.Format("0b{0}", Convert.ToString(programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION), 2).PadLeft(8, '0'));
lvSpecial.Items[4].SubItems[1].Text = string.Format("{0}ms", programm.Stepcount * int.Parse(insertTime.Text));
lvSpecial.Items[5].SubItems[1].Text = "0b" + Convert.ToString(programm.Register[PICProgramm.ADDR_PORT_A], 2).PadLeft(8, '0');
lvSpecial.Items[6].SubItems[1].Text = "0b" + Convert.ToString(programm.Register[PICProgramm.ADDR_PORT_B], 2).PadLeft(8, '0');
lvSpecial.Items[7].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_C) ? "1" : "0";
lvSpecial.Items[8].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_DC) ? "1" : "0";
lvSpecial.Items[9].SubItems[1].Text = programm.GetRegisterOhneBank(PICProgramm.ADDR_STATUS, PICProgramm.STATUS_BIT_Z) ? "1" : "0";
lbStack.Items.Clear();
foreach (var u in programm.Stack) lbStack.Items.Add(u.ToString());
@ -322,56 +324,64 @@ namespace PIC_Simulator
private void btn_RA_7_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 7, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 7));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 7)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 7, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 7));
OberflaecheAktualisieren();
}
private void btn_RA_6_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 6, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 6));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 6)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 6, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 6));
OberflaecheAktualisieren();
}
private void btn_RA_5_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 5, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 5));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 5)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 5, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 5));
OberflaecheAktualisieren();
}
private void btn_RA_4_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 4, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 4));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 4)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 4, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 4));
OberflaecheAktualisieren();
}
private void btn_RA_3_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 3, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 3));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 3)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 3, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 3));
OberflaecheAktualisieren();
}
private void btn_RA_2_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 2, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 2));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 2)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 2, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 2));
OberflaecheAktualisieren();
}
private void btn_RA_1_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 1, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 1));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 1)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 1, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 1));
OberflaecheAktualisieren();
}
private void btn_RA_0_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 0, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 0));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, 0)) return;
programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_A], 0, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_A], 0));
OberflaecheAktualisieren();
}
@ -434,56 +444,64 @@ namespace PIC_Simulator
private void btn_RB_7_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 7, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 7));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 7)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 7, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 7));
OberflaecheAktualisieren();
}
private void btn_RB_6_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 6, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 6));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 6)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 6, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 6));
OberflaecheAktualisieren();
}
private void btn_RB_5_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 5, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 5));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 5)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 5, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 5));
OberflaecheAktualisieren();
}
private void btn_RB_4_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 4, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 4));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 4)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 4, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 4));
OberflaecheAktualisieren();
}
private void btn_RB_3_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 3, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 3));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 3)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 3, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 3));
OberflaecheAktualisieren();
}
private void btn_RB_2_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 2, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 2));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 2)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 2, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 2));
OberflaecheAktualisieren();
}
private void btn_RB_1_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 1, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 1));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 1)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 1, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 1));
OberflaecheAktualisieren();
}
private void btn_RB_0_Click(object sender, EventArgs e)
{
if (programm == null) return;
programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 0, !programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_B, 0));
if (!programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, 0)) return;
programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(programm.Register[PICProgramm.ADDR_PORT_B], 0, !PICProgramm.GetBit(programm.Register[PICProgramm.ADDR_PORT_B], 0));
OberflaecheAktualisieren();
}

View File

@ -239,6 +239,8 @@ namespace PIC_Simulator.PIC
if (IsSleeping) return false;
uint cycleCount = 1;
if (aktueller_befehl.befehl == ADDWF)
{
// Add the contents of the W register with
@ -673,6 +675,7 @@ namespace PIC_Simulator.PIC
// GOTO is a two cycle instruction.
PCCounter = befehle.FindIndex(b => b.labelnummer == aktueller_befehl.parameter_k) - 1;
cycleCount = 2;
}
else if (aktueller_befehl.befehl == IORLW)
{
@ -714,6 +717,7 @@ namespace PIC_Simulator.PIC
// instruction.
Register_W = (byte)aktueller_befehl.parameter_k;
PCCounter = (int) Stack.Pop();
cycleCount = 2;
}
else if (aktueller_befehl.befehl == RETURN)
{
@ -722,6 +726,7 @@ namespace PIC_Simulator.PIC
// is loaded into the program counter.This
// is a two cycle instruction.
PCCounter = (int)Stack.Pop();
cycleCount = 2;
}
else if (aktueller_befehl.befehl == SLEEP)
{
@ -790,9 +795,103 @@ namespace PIC_Simulator.PIC
PCCounter++;
Stepcount++;
TimerBerechnen(cycleCount);
return PCCounter >= befehle.Count;
}
private bool prev_RA4 = false;
private void TimerBerechnen(uint cycles)
{
bool tmr_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_T0CS);
bool edge_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_T0SE);
if (!tmr_mode)
{
bool curr_A4 = GetRegisterOhneBank(ADDR_PORT_A, 4);
if (edge_mode)
{
if (prev_RA4 && !curr_A4)
{
TimerHochzaehlen(cycles);
}
}
else
{
if (!prev_RA4 && curr_A4)
{
TimerHochzaehlen(cycles);
}
}
}
else
{
TimerHochzaehlen(cycles);
}
prev_RA4 = GetRegisterOhneBank(ADDR_PORT_A, 4);
}
private uint prescale_cntr = 0; // Zähler für timer
private void TimerHochzaehlen(uint cycles)
{
uint current = GetRegisterOhneBank(ADDR_TMR0);
uint scale = BerechneVorskalierung();
prescale_cntr += cycles;
while (prescale_cntr >= scale)
{
prescale_cntr -= scale;
uint Result = current + 1;
if (Result > 0xFF)
{
//TODO Interrupt PIT_TIMER
}
Result %= 0x100;
uint tmp_psc = prescale_cntr;
SetRegisterOhneBank(ADDR_TMR0, Result);
prescale_cntr = tmp_psc;
}
}
private uint BerechneVorskalierung()
{
bool prescale_mode = GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PSA);
uint scale = 0;
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS2) ? 1U : 0U;
scale *= 2;
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS1) ? 1U : 0U;
scale *= 2;
scale += GetRegisterOhneBank(ADDR_OPTION, OPTION_BIT_PS0) ? 1U : 0U;
return prescale_mode ? 1 : (SHL(2, scale));
}
private uint UIntPower(uint x, uint power)
{
if (power == 0)
return 1;
if (power == 1)
return x;
// ----------------------
int n = 15;
while ((power <<= 1) >= 0)
n--;
uint tmp = x;
while (--n > 0)
tmp = tmp * tmp *
(((power <<= 1) < 0) ? x : 1);
return tmp;
}
public void SetRegisterOhneBank(uint index, uint wert)
{
// register die nur einmal auf bank1 + 2 existieren
@ -866,9 +965,6 @@ namespace PIC_Simulator.PIC
return Register[Register[ADDR_FSR]];
}
if (index == ADDR_PORT_A) return Latch_RA;
if (index == ADDR_PORT_A) return Latch_RB;
return Register[index];
}
@ -901,7 +997,6 @@ namespace PIC_Simulator.PIC
SetRegisterOhneBank(index, SetBit(GetRegisterOhneBank(index), bit, wert));
}
private void SetRegister(uint index, uint bit, bool wert)
{
SetRegister(index, SetBit(GetRegister(index), bit, wert));
@ -928,7 +1023,7 @@ namespace PIC_Simulator.PIC
return (xa + xb) > 0x0F;
}
public static bool GetBit(uint val, uint pos)
public static bool GetBit(byte val, uint pos)
{
return (val & SHL(1, pos)) != 0;
}
@ -943,9 +1038,9 @@ namespace PIC_Simulator.PIC
return (uint)((val) >> ((int)steps));
}
public static uint SetBit(uint val, uint pos, bool bit)
public static byte SetBit(byte val, uint pos, bool bit)
{
return bit ? (val | SHL(1, pos)) : (val & ~SHL(1, pos));
return (byte)(bit ? (val | SHL(1, pos)) : (val & ~SHL(1, pos)));
}
}

View File

@ -135,8 +135,16 @@ namespace PIC_Simulator.PIC
}
else
{
Programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_A, v.Item1);
Programm.SetRegisterOhneBank(PICProgramm.ADDR_PORT_B, v.Item2);
for (uint i = 0; i < 8; i++)
{
// Nur 'i' bits übernehmen
if (Programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_A, i))
Programm.Register[PICProgramm.ADDR_PORT_A] = PICProgramm.SetBit(Programm.Register[PICProgramm.ADDR_PORT_A], i, !PICProgramm.GetBit((byte)v.Item1, i));
if (Programm.GetRegisterOhneBank(PICProgramm.ADDR_TRIS_B, i))
Programm.Register[PICProgramm.ADDR_PORT_B] = PICProgramm.SetBit(Programm.Register[PICProgramm.ADDR_PORT_B], i, !PICProgramm.GetBit((byte)v.Item1, i));
}
Fenster.OberflaecheAktualisieren();
}
}