1 |
|
/* |
2 |
|
* CIA_SC.cpp - Single-cycle 6526 emulation |
3 |
|
* |
4 |
< |
* Frodo (C) 1994-1997,2002 Christian Bauer |
4 |
> |
* Frodo Copyright (C) Christian Bauer |
5 |
|
* |
6 |
|
* This program is free software; you can redistribute it and/or modify |
7 |
|
* it under the terms of the GNU General Public License as published by |
58 |
|
T_LOAD_THEN_COUNT, |
59 |
|
T_LOAD_THEN_WAIT_THEN_COUNT, |
60 |
|
T_COUNT, |
61 |
< |
T_COUNT_THEN_STOP, |
61 |
> |
T_COUNT_THEN_STOP |
62 |
|
}; |
63 |
|
|
64 |
|
|
93 |
|
ta_cnt_phi2 = tb_cnt_phi2 = tb_cnt_ta = false; |
94 |
|
|
95 |
|
ta_irq_next_cycle = tb_irq_next_cycle = false; |
96 |
+ |
has_new_cra = has_new_crb = false; |
97 |
+ |
ta_toggle = tb_toggle = false; |
98 |
|
ta_state = tb_state = T_STOP; |
99 |
|
} |
100 |
|
|
201 |
|
|
202 |
|
|
203 |
|
/* |
204 |
+ |
* Output TA/TB to PB6/7 |
205 |
+ |
*/ |
206 |
+ |
|
207 |
+ |
inline uint8 MOS6526::timer_on_pb(uint8 prb) |
208 |
+ |
{ |
209 |
+ |
if (cra & 0x02) { |
210 |
+ |
|
211 |
+ |
// TA output to PB6 |
212 |
+ |
if ((cra & 0x04) ? ta_toggle : ta_irq_next_cycle) { |
213 |
+ |
prb |= 0x40; |
214 |
+ |
} else { |
215 |
+ |
prb &= 0xbf; |
216 |
+ |
} |
217 |
+ |
} |
218 |
+ |
|
219 |
+ |
if (crb & 0x02) { |
220 |
+ |
|
221 |
+ |
// TB output to PB7 |
222 |
+ |
if ((crb & 0x04) ? tb_toggle : tb_irq_next_cycle) { |
223 |
+ |
prb |= 0x80; |
224 |
+ |
} else { |
225 |
+ |
prb &= 0x7f; |
226 |
+ |
} |
227 |
+ |
} |
228 |
+ |
|
229 |
+ |
return prb; |
230 |
+ |
} |
231 |
+ |
|
232 |
+ |
|
233 |
+ |
/* |
234 |
|
* Read from register (CIA 1) |
235 |
|
*/ |
236 |
|
|
259 |
|
if (!(tst & 0x20)) ret &= KeyMatrix[5]; |
260 |
|
if (!(tst & 0x40)) ret &= KeyMatrix[6]; |
261 |
|
if (!(tst & 0x80)) ret &= KeyMatrix[7]; |
262 |
< |
return (ret | (prb & ddrb)) & Joystick1; |
262 |
> |
ret = (ret | (prb & ddrb)) & Joystick1; |
263 |
> |
|
264 |
> |
// TA/TB output to PB enabled? |
265 |
> |
if ((cra | crb) & 0x02) |
266 |
> |
ret = timer_on_pb(ret); |
267 |
> |
|
268 |
> |
return ret; |
269 |
|
} |
270 |
|
case 0x02: return ddra; |
271 |
|
case 0x03: return ddrb; |
301 |
|
case 0x00: |
302 |
|
return (pra | ~ddra) & 0x3f |
303 |
|
| IECLines & the_cpu_1541->IECLines; |
304 |
< |
case 0x01: return prb | ~ddrb; |
304 |
> |
case 0x01: { |
305 |
> |
uint8 ret = prb | ~ddrb; |
306 |
> |
|
307 |
> |
// TA/TB output to PB enabled? |
308 |
> |
if ((cra | crb) & 0x02) |
309 |
> |
ret = timer_on_pb(ret); |
310 |
> |
|
311 |
> |
return ret; |
312 |
> |
} |
313 |
|
case 0x02: return ddra; |
314 |
|
case 0x03: return ddrb; |
315 |
|
case 0x04: return ta; |
409 |
|
int_mask |= byte & 0x7f; |
410 |
|
else |
411 |
|
int_mask &= ~byte; |
412 |
< |
if (icr & int_mask & 0x1f) { // Trigger IRQ if pending |
412 |
> |
if (icr & int_mask & 0x7f) { // Trigger IRQ if pending |
413 |
|
icr |= 0x80; |
414 |
|
the_cpu->TriggerCIAIRQ(); |
415 |
|
} |
577 |
|
ta = latcha; // Reload timer |
578 |
|
ta_irq_next_cycle = true; // Trigger interrupt in next cycle |
579 |
|
icr |= 1; // But set ICR bit now |
580 |
+ |
ta_toggle = !ta_toggle; // Toggle PB6 output |
581 |
|
|
582 |
|
if (cra & 8) { // One-shot? |
583 |
|
cra &= 0xfe; // Yes, stop timer |
596 |
|
case T_STOP: |
597 |
|
case T_LOAD_THEN_STOP: |
598 |
|
if (new_cra & 1) { // Timer started, wasn't running |
599 |
+ |
ta_toggle = true; // Starting the timer resets the toggle bit |
600 |
|
if (new_cra & 0x10) // Force load |
601 |
|
ta_state = T_LOAD_THEN_WAIT_THEN_COUNT; |
602 |
|
else // No force load |
647 |
|
case T_LOAD_THEN_COUNT: |
648 |
|
tb_state = T_COUNT; |
649 |
|
tb = latchb; // Reload timer |
650 |
< |
goto ta_idle; |
650 |
> |
goto tb_idle; |
651 |
|
case T_LOAD_THEN_WAIT_THEN_COUNT: |
652 |
|
tb_state = T_WAIT_THEN_COUNT; |
653 |
|
if (tb == 1) |
672 |
|
tb = latchb; // Reload timer |
673 |
|
tb_irq_next_cycle = true; // Trigger interrupt in next cycle |
674 |
|
icr |= 2; // But set ICR bit now |
675 |
+ |
tb_toggle = !tb_toggle; // Toggle PB7 output |
676 |
|
|
677 |
|
if (crb & 8) { // One-shot? |
678 |
|
crb &= 0xfe; // Yes, stop timer |
690 |
|
case T_STOP: |
691 |
|
case T_LOAD_THEN_STOP: |
692 |
|
if (new_crb & 1) { // Timer started, wasn't running |
693 |
+ |
tb_toggle = true; // Starting the timer resets the toggle bit |
694 |
|
if (new_crb & 0x10) // Force load |
695 |
|
tb_state = T_LOAD_THEN_WAIT_THEN_COUNT; |
696 |
|
else // No force load |