Watchdoggo
This commit is contained in:
87
PIC_Simulator/PIC/PICTimer.cs
Normal file
87
PIC_Simulator/PIC/PICTimer.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
|
||||
namespace PIC_Simulator.PIC
|
||||
{
|
||||
class PICTimer
|
||||
{
|
||||
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);
|
||||
|
||||
if (!tmr_mode)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
private uint prescale_cntr = 0; // Zähler für timer
|
||||
|
||||
private void TimerHochzaehlen(uint cycles)
|
||||
{
|
||||
uint current = programm.GetRegisterOhneBank(PICProgramm.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;
|
||||
programm.SetRegisterOhneBank(PICProgramm.ADDR_TMR0, Result);
|
||||
prescale_cntr = tmp_psc;
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user