37 m_mutex = xSemaphoreCreateMutex();
43 vSemaphoreDelete(m_mutex);
48 void PIT8253::runAutoTick(
int freq,
int updatesPerSec)
50 m_autoTickFreq = freq;
51 m_updatesPerSec = updatesPerSec;
52 xTaskCreatePinnedToCore(&autoTickTask,
"", 2048,
this, 5, &m_taskHandle, CoreUsage::busiestCore());
56 void PIT8253::autoTickTask(
void * pvParameters)
58 auto p = (PIT8253*)pvParameters;
60 const int ticks = p->m_autoTickFreq / p->m_updatesPerSec;
61 const int delay_ms = 1000 / p->m_updatesPerSec / portTICK_PERIOD_MS;
74 AutoSemaphore autoSemaphore(m_mutex);
75 m_timer[0] = {
false, 3, 3, 0, 0, 0, -1,
true,
false,
false,
false };
76 m_timer[1] = {
false, 3, 3, 0, 0, 0, -1,
true,
false,
false,
false };
77 m_timer[2] = {
false, 3, 3, 0, 0, 0, -1,
true,
false,
false,
false };
81 void PIT8253::write(
int reg, uint8_t value)
83 AutoSemaphore autoSemaphore(m_mutex);
90 timerIndex = (value >> 6) & 0x03;
92 int RLMode = (value >> 4) & 0x03;
95 m_timer[timerIndex].latch = m_timer[timerIndex].count;
96 m_timer[timerIndex].LSBToggle =
true;
99 m_timer[timerIndex].mode = (value >> 1) & 0x07;
100 m_timer[timerIndex].BCD = (value & 1) == 1;
101 m_timer[timerIndex].RLMode = RLMode;
103 m_timer[timerIndex].LSBToggle =
true;
108 printf(
"8253, read back. Required 8254?\n");
114 bool writeLSB =
false;
116 switch (m_timer[timerIndex].RLMode) {
121 writeLSB = m_timer[timerIndex].LSBToggle;
122 m_timer[timerIndex].LSBToggle = !m_timer[timerIndex].LSBToggle;
129 m_timer[timerIndex].resetHolding = (m_timer[timerIndex].resetHolding & 0xFF00) | value;
133 m_timer[timerIndex].resetHolding = (m_timer[timerIndex].resetHolding & 0x00FF) | (((
int)value) << 8);
134 m_timer[timerIndex].resetCount = m_timer[timerIndex].resetHolding;
135 if (m_timer[timerIndex].mode == 0) {
136 m_timer[timerIndex].count = (uint16_t)(m_timer[timerIndex].resetCount - 1);
141 changeOut(timerIndex, m_timer[timerIndex].mode != 0);
148 uint8_t PIT8253::read(
int reg)
150 AutoSemaphore autoSemaphore(m_mutex);
156 int timerIndex = reg;
158 int readValue = m_timer[timerIndex].latch != -1 ? m_timer[timerIndex].latch : m_timer[timerIndex].count;
160 bool readLSB =
false;
161 if (m_timer[timerIndex].RLMode == 1) {
163 }
else if (m_timer[timerIndex].RLMode == 3) {
164 readLSB = m_timer[timerIndex].LSBToggle;
165 m_timer[timerIndex].LSBToggle = !m_timer[timerIndex].LSBToggle;
169 value = readValue & 0xFF;
171 value = (readValue >> 8) & 0xFF;
172 m_timer[timerIndex].latch = -1;
184 void PIT8253::setGate(
int timerIndex,
bool value)
186 AutoSemaphore autoSemaphore(m_mutex);
187 switch (m_timer[timerIndex].mode) {
192 m_timer[timerIndex].running = value;
197 if (m_timer[timerIndex].gate ==
false && value ==
true)
198 m_timer[timerIndex].running =
true;
201 m_timer[timerIndex].gate = value;
205 void PIT8253::changeOut(
int timer,
bool value)
207 if (value != m_timer[timer].out) {
209 m_timer[timer].out = value;
210 m_changeOut(m_context, timer);
215 void PIT8253::tick(
int ticks)
217 AutoSemaphore autoSemaphore(m_mutex);
219 m_tick(m_context, ticks);
223 void PIT8253::unsafeTick(
int ticks)
225 for (
int timerIndex = 0; timerIndex < 3; ++timerIndex) {
227 if (m_timer[timerIndex].running) {
230 if (m_timer[timerIndex].mode >= 4 && m_timer[timerIndex].out ==
false) {
232 changeOut(timerIndex,
true);
233 m_timer[timerIndex].running =
false;
234 m_timer[timerIndex].count = 65535;
238 m_timer[timerIndex].count -= ticks;
241 if (m_timer[timerIndex].mode == 3)
242 m_timer[timerIndex].count -= ticks;
244 if (m_timer[timerIndex].count <= 0) {
246 if (m_timer[timerIndex].resetCount == 0) {
247 m_timer[timerIndex].count += 65536;
249 m_timer[timerIndex].count += m_timer[timerIndex].resetCount;
251 switch (m_timer[timerIndex].mode) {
254 changeOut(timerIndex,
true);
258 changeOut(timerIndex,
true);
261 changeOut(timerIndex,
false);
264 changeOut(timerIndex, !m_timer[timerIndex].out);
269 switch (m_timer[timerIndex].mode) {
272 changeOut(timerIndex,
false);
275 changeOut(timerIndex,
true);
280 changeOut(timerIndex,
false);