Timer (~)

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

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