Timer (~)
This commit is contained in:
@@ -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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -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();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user