ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CIA_SC.cpp
Revision: 1.8
Committed: 2010-04-25T12:02:13Z (12 years, 9 months ago) by cebix
Branch: MAIN
CVS Tags: HEAD
Changes since 1.7: +52 -3 lines
Log Message:
TA/TB output to PB6/PB7

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * CIA_SC.cpp - Single-cycle 6526 emulation
3     *
4 cebix 1.7 * Frodo Copyright (C) Christian Bauer
5 cebix 1.1 *
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
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19     */
20    
21     /*
22     * Notes:
23     * ------
24     *
25     * - The Emulate() function is called for every emulated Phi2
26     * clock cycle. It counts down the timers and triggers
27     * interrupts if necessary.
28     * - The TOD clocks are counted by CountTOD() during the VBlank, so
29     * the input frequency is 50Hz
30     * - The fields KeyMatrix and RevMatrix contain one bit for each
31     * key on the C64 keyboard (0: key pressed, 1: key released).
32     * KeyMatrix is used for normal keyboard polling (PRA->PRB),
33     * RevMatrix for reversed polling (PRB->PRA).
34     *
35     * Incompatibilities:
36     * ------------------
37     *
38     * - The TOD clock should not be stopped on a read access, but be
39     * latched
40     * - The SDR interrupt is faked
41     * - Some small incompatibilities with the timers
42     */
43    
44     #include "sysdeps.h"
45    
46     #include "CIA.h"
47     #include "CPUC64.h"
48     #include "CPU1541.h"
49     #include "VIC.h"
50     #include "Prefs.h"
51    
52    
53     // Timer states
54     enum {
55     T_STOP,
56     T_WAIT_THEN_COUNT,
57     T_LOAD_THEN_STOP,
58     T_LOAD_THEN_COUNT,
59     T_LOAD_THEN_WAIT_THEN_COUNT,
60     T_COUNT,
61 cebix 1.3 T_COUNT_THEN_STOP
62 cebix 1.1 };
63    
64    
65     /*
66     * Constructors
67     */
68    
69     MOS6526::MOS6526(MOS6510 *CPU) : the_cpu(CPU) {}
70     MOS6526_1::MOS6526_1(MOS6510 *CPU, MOS6569 *VIC) : MOS6526(CPU), the_vic(VIC) {}
71     MOS6526_2::MOS6526_2(MOS6510 *CPU, MOS6569 *VIC, MOS6502_1541 *CPU1541) : MOS6526(CPU), the_vic(VIC), the_cpu_1541(CPU1541) {}
72    
73    
74     /*
75     * Reset the CIA
76     */
77    
78     void MOS6526::Reset(void)
79     {
80     pra = prb = ddra = ddrb = 0;
81    
82     ta = tb = 0xffff;
83     latcha = latchb = 1;
84    
85     tod_10ths = tod_sec = tod_min = tod_hr = 0;
86     alm_10ths = alm_sec = alm_min = alm_hr = 0;
87    
88     sdr = icr = cra = crb = int_mask = 0;
89    
90     tod_halt = false;
91     tod_divider = 0;
92    
93     ta_cnt_phi2 = tb_cnt_phi2 = tb_cnt_ta = false;
94    
95     ta_irq_next_cycle = tb_irq_next_cycle = false;
96 cebix 1.7 has_new_cra = has_new_crb = false;
97 cebix 1.8 ta_toggle = tb_toggle = false;
98 cebix 1.1 ta_state = tb_state = T_STOP;
99     }
100    
101     void MOS6526_1::Reset(void)
102     {
103     MOS6526::Reset();
104    
105     // Clear keyboard matrix and joystick states
106     for (int i=0; i<8; i++)
107     KeyMatrix[i] = RevMatrix[i] = 0xff;
108    
109     Joystick1 = Joystick2 = 0xff;
110     prev_lp = 0x10;
111     }
112    
113     void MOS6526_2::Reset(void)
114     {
115     MOS6526::Reset();
116    
117     // VA14/15 = 0
118     the_vic->ChangedVA(0);
119    
120     // IEC
121     IECLines = 0xd0;
122     }
123    
124    
125     /*
126     * Get CIA state
127     */
128    
129     void MOS6526::GetState(MOS6526State *cs)
130     {
131     cs->pra = pra;
132     cs->prb = prb;
133     cs->ddra = ddra;
134     cs->ddrb = ddrb;
135    
136     cs->ta_lo = ta & 0xff;
137     cs->ta_hi = ta >> 8;
138     cs->tb_lo = tb & 0xff;
139     cs->tb_hi = tb >> 8;
140     cs->latcha = latcha;
141     cs->latchb = latchb;
142     cs->cra = cra;
143     cs->crb = crb;
144    
145     cs->tod_10ths = tod_10ths;
146     cs->tod_sec = tod_sec;
147     cs->tod_min = tod_min;
148     cs->tod_hr = tod_hr;
149     cs->alm_10ths = alm_10ths;
150     cs->alm_sec = alm_sec;
151     cs->alm_min = alm_min;
152     cs->alm_hr = alm_hr;
153    
154     cs->sdr = sdr;
155    
156     cs->int_data = icr;
157     cs->int_mask = int_mask;
158     }
159    
160    
161     /*
162     * Restore CIA state
163     */
164    
165     void MOS6526::SetState(MOS6526State *cs)
166     {
167     pra = cs->pra;
168     prb = cs->prb;
169     ddra = cs->ddra;
170     ddrb = cs->ddrb;
171    
172     ta = (cs->ta_hi << 8) | cs->ta_lo;
173     tb = (cs->tb_hi << 8) | cs->tb_lo;
174     latcha = cs->latcha;
175     latchb = cs->latchb;
176     cra = cs->cra;
177     crb = cs->crb;
178    
179     tod_10ths = cs->tod_10ths;
180     tod_sec = cs->tod_sec;
181     tod_min = cs->tod_min;
182     tod_hr = cs->tod_hr;
183     alm_10ths = cs->alm_10ths;
184     alm_sec = cs->alm_sec;
185     alm_min = cs->alm_min;
186     alm_hr = cs->alm_hr;
187    
188     sdr = cs->sdr;
189    
190     icr = cs->int_data;
191     int_mask = cs->int_mask;
192    
193     tod_halt = false;
194     ta_cnt_phi2 = ((cra & 0x20) == 0x00);
195     tb_cnt_phi2 = ((crb & 0x60) == 0x00);
196     tb_cnt_ta = ((crb & 0x60) == 0x40);
197    
198     ta_state = (cra & 1) ? T_COUNT : T_STOP;
199     tb_state = (crb & 1) ? T_COUNT : T_STOP;
200     }
201    
202    
203     /*
204 cebix 1.8 * 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 cebix 1.1 * Read from register (CIA 1)
235     */
236    
237     uint8 MOS6526_1::ReadRegister(uint16 adr)
238     {
239     switch (adr) {
240     case 0x00: {
241     uint8 ret = pra | ~ddra, tst = (prb | ~ddrb) & Joystick1;
242     if (!(tst & 0x01)) ret &= RevMatrix[0]; // AND all active columns
243     if (!(tst & 0x02)) ret &= RevMatrix[1];
244     if (!(tst & 0x04)) ret &= RevMatrix[2];
245     if (!(tst & 0x08)) ret &= RevMatrix[3];
246     if (!(tst & 0x10)) ret &= RevMatrix[4];
247     if (!(tst & 0x20)) ret &= RevMatrix[5];
248     if (!(tst & 0x40)) ret &= RevMatrix[6];
249     if (!(tst & 0x80)) ret &= RevMatrix[7];
250     return ret & Joystick2;
251     }
252     case 0x01: {
253     uint8 ret = ~ddrb, tst = (pra | ~ddra) & Joystick2;
254     if (!(tst & 0x01)) ret &= KeyMatrix[0]; // AND all active rows
255     if (!(tst & 0x02)) ret &= KeyMatrix[1];
256     if (!(tst & 0x04)) ret &= KeyMatrix[2];
257     if (!(tst & 0x08)) ret &= KeyMatrix[3];
258     if (!(tst & 0x10)) ret &= KeyMatrix[4];
259     if (!(tst & 0x20)) ret &= KeyMatrix[5];
260     if (!(tst & 0x40)) ret &= KeyMatrix[6];
261     if (!(tst & 0x80)) ret &= KeyMatrix[7];
262 cebix 1.8 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 cebix 1.1 }
270     case 0x02: return ddra;
271     case 0x03: return ddrb;
272     case 0x04: return ta;
273     case 0x05: return ta >> 8;
274     case 0x06: return tb;
275     case 0x07: return tb >> 8;
276     case 0x08: tod_halt = false; return tod_10ths;
277     case 0x09: return tod_sec;
278     case 0x0a: return tod_min;
279     case 0x0b: tod_halt = true; return tod_hr;
280     case 0x0c: return sdr;
281     case 0x0d: {
282     uint8 ret = icr; // Read and clear ICR
283     icr = 0;
284     the_cpu->ClearCIAIRQ(); // Clear IRQ
285     return ret;
286     }
287     case 0x0e: return cra;
288     case 0x0f: return crb;
289     }
290     return 0; // Can't happen
291     }
292    
293    
294     /*
295     * Read from register (CIA 2)
296     */
297    
298     uint8 MOS6526_2::ReadRegister(uint16 adr)
299     {
300     switch (adr) {
301     case 0x00:
302     return (pra | ~ddra) & 0x3f
303     | IECLines & the_cpu_1541->IECLines;
304 cebix 1.8 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 cebix 1.1 case 0x02: return ddra;
314     case 0x03: return ddrb;
315     case 0x04: return ta;
316     case 0x05: return ta >> 8;
317     case 0x06: return tb;
318     case 0x07: return tb >> 8;
319     case 0x08: tod_halt = false; return tod_10ths;
320     case 0x09: return tod_sec;
321     case 0x0a: return tod_min;
322     case 0x0b: tod_halt = true; return tod_hr;
323     case 0x0c: return sdr;
324     case 0x0d: {
325     uint8 ret = icr; // Read and clear ICR
326     icr = 0;
327     the_cpu->ClearNMI();
328     return ret;
329     }
330     case 0x0e: return cra;
331     case 0x0f: return crb;
332     }
333     return 0; // Can't happen
334     }
335    
336    
337     /*
338     * Write to register (CIA 1)
339     */
340    
341     // Write to port B, check for lightpen interrupt
342     inline void MOS6526_1::check_lp(void)
343     {
344     if ((prb | ~ddrb) & 0x10 != prev_lp)
345     the_vic->TriggerLightpen();
346     prev_lp = (prb | ~ddrb) & 0x10;
347     }
348    
349     void MOS6526_1::WriteRegister(uint16 adr, uint8 byte)
350     {
351     switch (adr) {
352     case 0x0: pra = byte; break;
353     case 0x1:
354     prb = byte;
355     check_lp();
356     break;
357     case 0x2: ddra = byte; break;
358     case 0x3:
359     ddrb = byte;
360     check_lp();
361     break;
362    
363     case 0x4: latcha = (latcha & 0xff00) | byte; break;
364     case 0x5:
365     latcha = (latcha & 0xff) | (byte << 8);
366     if (!(cra & 1)) // Reload timer if stopped
367     ta = latcha;
368     break;
369    
370     case 0x6: latchb = (latchb & 0xff00) | byte; break;
371     case 0x7:
372     latchb = (latchb & 0xff) | (byte << 8);
373     if (!(crb & 1)) // Reload timer if stopped
374     tb = latchb;
375     break;
376    
377     case 0x8:
378     if (crb & 0x80)
379     alm_10ths = byte & 0x0f;
380     else
381     tod_10ths = byte & 0x0f;
382     break;
383     case 0x9:
384     if (crb & 0x80)
385     alm_sec = byte & 0x7f;
386     else
387     tod_sec = byte & 0x7f;
388     break;
389     case 0xa:
390     if (crb & 0x80)
391     alm_min = byte & 0x7f;
392     else
393     tod_min = byte & 0x7f;
394     break;
395     case 0xb:
396     if (crb & 0x80)
397     alm_hr = byte & 0x9f;
398     else
399     tod_hr = byte & 0x9f;
400     break;
401    
402     case 0xc:
403     sdr = byte;
404     TriggerInterrupt(8); // Fake SDR interrupt for programs that need it
405     break;
406    
407     case 0xd:
408     if (byte & 0x80)
409     int_mask |= byte & 0x7f;
410     else
411     int_mask &= ~byte;
412 cebix 1.8 if (icr & int_mask & 0x7f) { // Trigger IRQ if pending
413 cebix 1.1 icr |= 0x80;
414     the_cpu->TriggerCIAIRQ();
415     }
416     break;
417    
418     case 0xe:
419     has_new_cra = true; // Delay write by 1 cycle
420     new_cra = byte;
421     ta_cnt_phi2 = ((byte & 0x20) == 0x00);
422     break;
423    
424     case 0xf:
425     has_new_crb = true; // Delay write by 1 cycle
426     new_crb = byte;
427     tb_cnt_phi2 = ((byte & 0x60) == 0x00);
428     tb_cnt_ta = ((byte & 0x60) == 0x40);
429     break;
430     }
431     }
432    
433    
434     /*
435     * Write to register (CIA 2)
436     */
437    
438     void MOS6526_2::WriteRegister(uint16 adr, uint8 byte)
439     {
440     switch (adr) {
441     case 0x0:{
442     pra = byte;
443     the_vic->ChangedVA(~(pra | ~ddra) & 3);
444     uint8 old_lines = IECLines;
445     IECLines = (~byte << 2) & 0x80 // DATA
446     | (~byte << 2) & 0x40 // CLK
447     | (~byte << 1) & 0x10; // ATN
448     if ((IECLines ^ old_lines) & 0x10) { // ATN changed
449     the_cpu_1541->NewATNState();
450     if (old_lines & 0x10) // ATN 1->0
451     the_cpu_1541->IECInterrupt();
452     }
453     break;
454     }
455     case 0x1: prb = byte; break;
456    
457     case 0x2:
458     ddra = byte;
459     the_vic->ChangedVA(~(pra | ~ddra) & 3);
460     break;
461     case 0x3: ddrb = byte; break;
462    
463     case 0x4: latcha = (latcha & 0xff00) | byte; break;
464     case 0x5:
465     latcha = (latcha & 0xff) | (byte << 8);
466     if (!(cra & 1)) // Reload timer if stopped
467     ta = latcha;
468     break;
469    
470     case 0x6: latchb = (latchb & 0xff00) | byte; break;
471     case 0x7:
472     latchb = (latchb & 0xff) | (byte << 8);
473     if (!(crb & 1)) // Reload timer if stopped
474     tb = latchb;
475     break;
476    
477     case 0x8:
478     if (crb & 0x80)
479     alm_10ths = byte & 0x0f;
480     else
481     tod_10ths = byte & 0x0f;
482     break;
483     case 0x9:
484     if (crb & 0x80)
485     alm_sec = byte & 0x7f;
486     else
487     tod_sec = byte & 0x7f;
488     break;
489     case 0xa:
490     if (crb & 0x80)
491     alm_min = byte & 0x7f;
492     else
493     tod_min = byte & 0x7f;
494     break;
495     case 0xb:
496     if (crb & 0x80)
497     alm_hr = byte & 0x9f;
498     else
499     tod_hr = byte & 0x9f;
500     break;
501    
502     case 0xc:
503     sdr = byte;
504     TriggerInterrupt(8); // Fake SDR interrupt for programs that need it
505     break;
506    
507     case 0xd:
508     if (byte & 0x80)
509     int_mask |= byte & 0x7f;
510     else
511     int_mask &= ~byte;
512     if (icr & int_mask & 0x1f) { // Trigger NMI if pending
513     icr |= 0x80;
514     the_cpu->TriggerNMI();
515     }
516     break;
517    
518     case 0xe:
519     has_new_cra = true; // Delay write by 1 cycle
520     new_cra = byte;
521     ta_cnt_phi2 = ((byte & 0x20) == 0x00);
522     break;
523    
524     case 0xf:
525     has_new_crb = true; // Delay write by 1 cycle
526     new_crb = byte;
527     tb_cnt_phi2 = ((byte & 0x60) == 0x00);
528     tb_cnt_ta = ((byte & 0x60) == 0x40);
529     break;
530     }
531     }
532    
533    
534     /*
535     * Emulate CIA for one cycle/raster line
536     */
537    
538     void MOS6526::EmulateCycle(void)
539     {
540     bool ta_underflow = false;
541    
542     // Timer A state machine
543     switch (ta_state) {
544     case T_WAIT_THEN_COUNT:
545     ta_state = T_COUNT; // fall through
546     case T_STOP:
547     goto ta_idle;
548     case T_LOAD_THEN_STOP:
549     ta_state = T_STOP;
550     ta = latcha; // Reload timer
551     goto ta_idle;
552     case T_LOAD_THEN_COUNT:
553     ta_state = T_COUNT;
554     ta = latcha; // Reload timer
555     goto ta_idle;
556     case T_LOAD_THEN_WAIT_THEN_COUNT:
557     ta_state = T_WAIT_THEN_COUNT;
558     if (ta == 1)
559     goto ta_interrupt; // Interrupt if timer == 1
560     else {
561     ta = latcha; // Reload timer
562     goto ta_idle;
563     }
564     case T_COUNT:
565     goto ta_count;
566     case T_COUNT_THEN_STOP:
567     ta_state = T_STOP;
568     goto ta_count;
569     }
570    
571     // Count timer A
572     ta_count:
573     if (ta_cnt_phi2)
574     if (!ta || !--ta) { // Decrement timer, underflow?
575     if (ta_state != T_STOP) {
576     ta_interrupt:
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 cebix 1.8 ta_toggle = !ta_toggle; // Toggle PB6 output
581 cebix 1.1
582     if (cra & 8) { // One-shot?
583     cra &= 0xfe; // Yes, stop timer
584     new_cra &= 0xfe;
585     ta_state = T_LOAD_THEN_STOP; // Reload in next cycle
586     } else
587     ta_state = T_LOAD_THEN_COUNT; // No, delay one cycle (and reload)
588     }
589     ta_underflow = true;
590     }
591    
592     // Delayed write to CRA?
593     ta_idle:
594     if (has_new_cra) {
595     switch (ta_state) {
596     case T_STOP:
597     case T_LOAD_THEN_STOP:
598     if (new_cra & 1) { // Timer started, wasn't running
599 cebix 1.8 ta_toggle = true; // Starting the timer resets the toggle bit
600 cebix 1.1 if (new_cra & 0x10) // Force load
601     ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
602     else // No force load
603     ta_state = T_WAIT_THEN_COUNT;
604     } else { // Timer stopped, was already stopped
605     if (new_cra & 0x10) // Force load
606     ta_state = T_LOAD_THEN_STOP;
607     }
608     break;
609     case T_COUNT:
610     if (new_cra & 1) { // Timer started, was already running
611     if (new_cra & 0x10) // Force load
612     ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
613     } else { // Timer stopped, was running
614     if (new_cra & 0x10) // Force load
615     ta_state = T_LOAD_THEN_STOP;
616     else // No force load
617     ta_state = T_COUNT_THEN_STOP;
618     }
619     break;
620     case T_LOAD_THEN_COUNT:
621     case T_WAIT_THEN_COUNT:
622     if (new_cra & 1) {
623     if (new_cra & 8) { // One-shot?
624     new_cra &= 0xfe; // Yes, stop timer
625     ta_state = T_STOP;
626     } else if (new_cra & 0x10) // Force load
627     ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
628     } else {
629     ta_state = T_STOP;
630     }
631     break;
632     }
633     cra = new_cra & 0xef;
634     has_new_cra = false;
635     }
636    
637     // Timer B state machine
638     switch (tb_state) {
639     case T_WAIT_THEN_COUNT:
640     tb_state = T_COUNT; // fall through
641     case T_STOP:
642     goto tb_idle;
643     case T_LOAD_THEN_STOP:
644     tb_state = T_STOP;
645     tb = latchb; // Reload timer
646     goto tb_idle;
647     case T_LOAD_THEN_COUNT:
648     tb_state = T_COUNT;
649     tb = latchb; // Reload timer
650 cebix 1.6 goto tb_idle;
651 cebix 1.1 case T_LOAD_THEN_WAIT_THEN_COUNT:
652     tb_state = T_WAIT_THEN_COUNT;
653     if (tb == 1)
654     goto tb_interrupt; // Interrupt if timer == 1
655     else {
656     tb = latchb; // Reload timer
657     goto tb_idle;
658     }
659     case T_COUNT:
660     goto tb_count;
661     case T_COUNT_THEN_STOP:
662     tb_state = T_STOP;
663     goto tb_count;
664     }
665    
666     // Count timer B
667     tb_count:
668     if (tb_cnt_phi2 || (tb_cnt_ta && ta_underflow))
669     if (!tb || !--tb) { // Decrement timer, underflow?
670     if (tb_state != T_STOP) {
671     tb_interrupt:
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 cebix 1.8 tb_toggle = !tb_toggle; // Toggle PB7 output
676 cebix 1.1
677     if (crb & 8) { // One-shot?
678     crb &= 0xfe; // Yes, stop timer
679     new_crb &= 0xfe;
680     tb_state = T_LOAD_THEN_STOP; // Reload in next cycle
681     } else
682     tb_state = T_LOAD_THEN_COUNT; // No, delay one cycle (and reload)
683     }
684     }
685    
686     // Delayed write to CRB?
687     tb_idle:
688     if (has_new_crb) {
689     switch (tb_state) {
690     case T_STOP:
691     case T_LOAD_THEN_STOP:
692     if (new_crb & 1) { // Timer started, wasn't running
693 cebix 1.8 tb_toggle = true; // Starting the timer resets the toggle bit
694 cebix 1.1 if (new_crb & 0x10) // Force load
695     tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
696     else // No force load
697     tb_state = T_WAIT_THEN_COUNT;
698     } else { // Timer stopped, was already stopped
699     if (new_crb & 0x10) // Force load
700     tb_state = T_LOAD_THEN_STOP;
701     }
702     break;
703     case T_COUNT:
704     if (new_crb & 1) { // Timer started, was already running
705     if (new_crb & 0x10) // Force load
706     tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
707     } else { // Timer stopped, was running
708     if (new_crb & 0x10) // Force load
709     tb_state = T_LOAD_THEN_STOP;
710     else // No force load
711     tb_state = T_COUNT_THEN_STOP;
712     }
713     break;
714     case T_LOAD_THEN_COUNT:
715     case T_WAIT_THEN_COUNT:
716     if (new_crb & 1) {
717     if (new_crb & 8) { // One-shot?
718     new_crb &= 0xfe; // Yes, stop timer
719     tb_state = T_STOP;
720     } else if (new_crb & 0x10) // Force load
721     tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
722     } else {
723     tb_state = T_STOP;
724     }
725     break;
726     }
727     crb = new_crb & 0xef;
728     has_new_crb = false;
729     }
730     }
731    
732    
733     /*
734     * Count CIA TOD clock (called during VBlank)
735     */
736    
737     void MOS6526::CountTOD(void)
738     {
739     uint8 lo, hi;
740    
741     // Decrement frequency divider
742     if (tod_divider)
743     tod_divider--;
744     else {
745    
746     // Reload divider according to 50/60 Hz flag
747     if (cra & 0x80)
748     tod_divider = 4;
749     else
750     tod_divider = 5;
751    
752     // 1/10 seconds
753     tod_10ths++;
754     if (tod_10ths > 9) {
755     tod_10ths = 0;
756    
757     // Seconds
758     lo = (tod_sec & 0x0f) + 1;
759     hi = tod_sec >> 4;
760     if (lo > 9) {
761     lo = 0;
762     hi++;
763     }
764     if (hi > 5) {
765     tod_sec = 0;
766    
767     // Minutes
768     lo = (tod_min & 0x0f) + 1;
769     hi = tod_min >> 4;
770     if (lo > 9) {
771     lo = 0;
772     hi++;
773     }
774     if (hi > 5) {
775     tod_min = 0;
776    
777     // Hours
778     lo = (tod_hr & 0x0f) + 1;
779     hi = (tod_hr >> 4) & 1;
780     tod_hr &= 0x80; // Keep AM/PM flag
781     if (lo > 9) {
782     lo = 0;
783     hi++;
784     }
785     tod_hr |= (hi << 4) | lo;
786     if ((tod_hr & 0x1f) > 0x11)
787     tod_hr = tod_hr & 0x80 ^ 0x80;
788     } else
789     tod_min = (hi << 4) | lo;
790     } else
791     tod_sec = (hi << 4) | lo;
792     }
793    
794     // Alarm time reached? Trigger interrupt if enabled
795     if (tod_10ths == alm_10ths && tod_sec == alm_sec &&
796     tod_min == alm_min && tod_hr == alm_hr)
797     TriggerInterrupt(4);
798     }
799     }
800    
801    
802     /*
803     * Trigger IRQ (CIA 1)
804     */
805    
806     void MOS6526_1::TriggerInterrupt(int bit)
807     {
808     icr |= bit;
809     if (int_mask & bit) {
810     icr |= 0x80;
811     the_cpu->TriggerCIAIRQ();
812     }
813     }
814    
815    
816     /*
817     * Trigger NMI (CIA 2)
818     */
819    
820     void MOS6526_2::TriggerInterrupt(int bit)
821     {
822     icr |= bit;
823     if (int_mask & bit) {
824     icr |= 0x80;
825     the_cpu->TriggerNMI();
826     }
827     }