2017-05-16 10:01:08 +02:00
|
|
|
|
|
|
|
|
|
namespace PIC_Simulator.PIC
|
|
|
|
|
{
|
2017-05-16 17:52:02 +02:00
|
|
|
|
public class PICTimer
|
2017-05-16 10:01:08 +02:00
|
|
|
|
{
|
|
|
|
|
private PICProgramm programm;
|
|
|
|
|
|
|
|
|
|
public PICTimer(PICProgramm p)
|
|
|
|
|
{
|
|
|
|
|
programm = p;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private bool prev_RA4 = false;
|
|
|
|
|
public void TimerBerechnen(uint cycles)
|
|
|
|
|
{
|
|
|
|
|
bool tmr_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_T0CS);
|
|
|
|
|
bool edge_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_T0SE);
|
|
|
|
|
|
2017-05-16 17:31:41 +02:00
|
|
|
|
if (tmr_mode)
|
2017-05-16 10:01:08 +02:00
|
|
|
|
{
|
|
|
|
|
bool curr_A4 = programm.GetRegisterOhneBank(PICProgramm.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 = programm.GetRegisterOhneBank(PICProgramm.ADDR_PORT_A, 4);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-16 17:31:41 +02:00
|
|
|
|
private uint count = 0; // Zähler für timer
|
2017-05-16 10:01:08 +02:00
|
|
|
|
|
|
|
|
|
private void TimerHochzaehlen(uint cycles)
|
|
|
|
|
{
|
2017-05-16 17:31:41 +02:00
|
|
|
|
uint current = programm.Register[PICProgramm.ADDR_TMR0];
|
2017-05-16 10:01:08 +02:00
|
|
|
|
uint scale = BerechneVorskalierung();
|
|
|
|
|
|
2017-05-16 17:31:41 +02:00
|
|
|
|
count += cycles;
|
2017-05-16 10:01:08 +02:00
|
|
|
|
|
2017-05-16 17:31:41 +02:00
|
|
|
|
while (count >= scale)
|
2017-05-16 10:01:08 +02:00
|
|
|
|
{
|
2017-05-16 17:31:41 +02:00
|
|
|
|
count -= scale;
|
2017-05-16 10:01:08 +02:00
|
|
|
|
|
|
|
|
|
uint Result = current + 1;
|
|
|
|
|
if (Result > 0xFF)
|
|
|
|
|
{
|
2017-05-16 10:11:35 +02:00
|
|
|
|
programm.TimerInterrupt();
|
2017-05-16 10:01:08 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Result %= 0x100;
|
|
|
|
|
|
2017-05-16 17:31:41 +02:00
|
|
|
|
uint tmp_psc = count;
|
|
|
|
|
programm.Register[PICProgramm.ADDR_TMR0] = (byte) Result;
|
|
|
|
|
count = tmp_psc;
|
2017-05-16 10:01:08 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private uint BerechneVorskalierung()
|
|
|
|
|
{
|
|
|
|
|
bool prescale_mode = programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PSA);
|
|
|
|
|
|
|
|
|
|
uint scale = 0;
|
|
|
|
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS2) ? 1U : 0U;
|
|
|
|
|
scale *= 2;
|
|
|
|
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS1) ? 1U : 0U;
|
|
|
|
|
scale *= 2;
|
|
|
|
|
scale += programm.GetRegisterOhneBank(PICProgramm.ADDR_OPTION, PICProgramm.OPTION_BIT_PS0) ? 1U : 0U;
|
|
|
|
|
|
|
|
|
|
return prescale_mode ? 1 : (PICProgramm.SHL(2, scale));
|
|
|
|
|
}
|
2017-05-16 17:31:41 +02:00
|
|
|
|
|
|
|
|
|
public void Reset()
|
|
|
|
|
{
|
|
|
|
|
count = 0;
|
|
|
|
|
}
|
2017-05-16 10:01:08 +02:00
|
|
|
|
}
|
|
|
|
|
}
|