39 FRC1Timer_init(PIT_FRC1_PRESCALER);
50 for (
int i = 0; i < 3; ++i) {
51 memset(&m_timer[i], 0,
sizeof(TimerInfo));
53 m_timer[i].RLMode = 3;
54 m_timer[i].latch = -1;
55 m_timer[i].LSBToggle =
true;
57 m_lastTickTime = FRC1Timer();
62void PIT8253::write(
int reg, uint8_t value)
71 int timerIndex = (value >> 6) & 0x03;
72 auto & timer = m_timer[timerIndex];
74 int RLMode = (value >> 4) & 0x03;
78 timer.latch = timer.count;
79 timer.LSBToggle =
true;
80 timer.ctrlSet =
false;
84 timer.mode = (value >> 1) & 0x07;
85 timer.BCD = (value & 1) == 1;
86 timer.RLMode = RLMode;
89 timer.LSBToggle =
true;
94 printf(
"8253, read back. Required 8254?\n");
100 int timerIndex = reg;
101 auto & timer = m_timer[timerIndex];
103 bool writeLSB =
false;
105 switch (timer.RLMode) {
110 writeLSB = timer.LSBToggle;
111 timer.LSBToggle = !timer.LSBToggle;
118 timer.resetHolding = (timer.resetHolding & 0xFF00) | value;
122 timer.resetHolding = (timer.resetHolding & 0x00FF) | (((
int)value) << 8);
123 timer.resetCount = timer.resetHolding;
125 timer.count = (uint16_t)(timer.resetCount - 1);
126 timer.ctrlSet =
false;
131 changeOut(timerIndex, timer.mode != 0);
138uint8_t PIT8253::read(
int reg)
147 auto & timer = m_timer[reg];
149 int readValue = timer.latch != -1 ? timer.latch : timer.count;
151 bool readLSB =
false;
152 if (timer.RLMode == 1) {
154 }
else if (timer.RLMode == 3) {
155 readLSB = timer.LSBToggle;
156 timer.LSBToggle = !timer.LSBToggle;
160 value = readValue & 0xFF;
162 value = (readValue >> 8) & 0xFF;
172void PIT8253::setGate(
int timerIndex,
bool value)
177 auto & timer = m_timer[timerIndex];
179 switch (timer.mode) {
184 timer.running = value;
189 if (timer.gate ==
false && value ==
true)
190 timer.running =
true;
193 switch (timer.mode) {
197 changeOut(timerIndex,
true);
200 if (!timer.gate && value)
201 timer.count = timer.resetCount;
207void PIT8253::changeOut(
int timer,
bool value)
209 if (value != m_timer[timer].out) {
211 m_timer[timer].out = value;
212 m_changeOut(m_context, timer);
219 uint32_t now = FRC1Timer();
220 int32_t diff = now - m_lastTickTime;
222 diff = FRC1TimerMax - m_lastTickTime + now;
224 constexpr uint32_t BITS = 10;
225 constexpr uint32_t INC = (PIT_TICK_FREQ << BITS) / PIT_FRC1_FREQUENCY;
228 int ticks = m_acc >> BITS;
229 m_acc &= (1 << BITS) - 1;
231 m_lastTickTime = now;
238 m_acc += (ticks - 65535) << BITS;
242 for (
int timerIndex = 0; timerIndex < 3; ++timerIndex) {
244 auto & timer = m_timer[timerIndex];
249 if (timer.mode >= 4 && timer.out ==
false) {
251 changeOut(timerIndex,
true);
252 timer.running =
false;
257 timer.count -= ticks;
261 timer.count -= ticks;
263 if (timer.count <= 0) {
265 timer.count += timer.resetCount == 0 ? 65536 : timer.resetCount;
266 switch (timer.mode) {
270 changeOut(timerIndex,
true);
273 changeOut(timerIndex,
false);
276 changeOut(timerIndex, !timer.out);
281 switch (timer.mode) {
286 changeOut(timerIndex,
false);
289 changeOut(timerIndex,
true);