ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CIA_SC.cpp
Revision: 1.7
Committed: 2010-04-21T19:54:13Z (13 years, 11 months ago) by cebix
Branch: MAIN
Changes since 1.6: +2 -1 lines
Log Message:
added missing initializations

File Contents

# Content
1 /*
2 * CIA_SC.cpp - Single-cycle 6526 emulation
3 *
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
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 T_COUNT_THEN_STOP
62 };
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 has_new_cra = has_new_crb = false;
97 ta_state = tb_state = T_STOP;
98 }
99
100 void MOS6526_1::Reset(void)
101 {
102 MOS6526::Reset();
103
104 // Clear keyboard matrix and joystick states
105 for (int i=0; i<8; i++)
106 KeyMatrix[i] = RevMatrix[i] = 0xff;
107
108 Joystick1 = Joystick2 = 0xff;
109 prev_lp = 0x10;
110 }
111
112 void MOS6526_2::Reset(void)
113 {
114 MOS6526::Reset();
115
116 // VA14/15 = 0
117 the_vic->ChangedVA(0);
118
119 // IEC
120 IECLines = 0xd0;
121 }
122
123
124 /*
125 * Get CIA state
126 */
127
128 void MOS6526::GetState(MOS6526State *cs)
129 {
130 cs->pra = pra;
131 cs->prb = prb;
132 cs->ddra = ddra;
133 cs->ddrb = ddrb;
134
135 cs->ta_lo = ta & 0xff;
136 cs->ta_hi = ta >> 8;
137 cs->tb_lo = tb & 0xff;
138 cs->tb_hi = tb >> 8;
139 cs->latcha = latcha;
140 cs->latchb = latchb;
141 cs->cra = cra;
142 cs->crb = crb;
143
144 cs->tod_10ths = tod_10ths;
145 cs->tod_sec = tod_sec;
146 cs->tod_min = tod_min;
147 cs->tod_hr = tod_hr;
148 cs->alm_10ths = alm_10ths;
149 cs->alm_sec = alm_sec;
150 cs->alm_min = alm_min;
151 cs->alm_hr = alm_hr;
152
153 cs->sdr = sdr;
154
155 cs->int_data = icr;
156 cs->int_mask = int_mask;
157 }
158
159
160 /*
161 * Restore CIA state
162 */
163
164 void MOS6526::SetState(MOS6526State *cs)
165 {
166 pra = cs->pra;
167 prb = cs->prb;
168 ddra = cs->ddra;
169 ddrb = cs->ddrb;
170
171 ta = (cs->ta_hi << 8) | cs->ta_lo;
172 tb = (cs->tb_hi << 8) | cs->tb_lo;
173 latcha = cs->latcha;
174 latchb = cs->latchb;
175 cra = cs->cra;
176 crb = cs->crb;
177
178 tod_10ths = cs->tod_10ths;
179 tod_sec = cs->tod_sec;
180 tod_min = cs->tod_min;
181 tod_hr = cs->tod_hr;
182 alm_10ths = cs->alm_10ths;
183 alm_sec = cs->alm_sec;
184 alm_min = cs->alm_min;
185 alm_hr = cs->alm_hr;
186
187 sdr = cs->sdr;
188
189 icr = cs->int_data;
190 int_mask = cs->int_mask;
191
192 tod_halt = false;
193 ta_cnt_phi2 = ((cra & 0x20) == 0x00);
194 tb_cnt_phi2 = ((crb & 0x60) == 0x00);
195 tb_cnt_ta = ((crb & 0x60) == 0x40);
196
197 ta_state = (cra & 1) ? T_COUNT : T_STOP;
198 tb_state = (crb & 1) ? T_COUNT : T_STOP;
199 }
200
201
202 /*
203 * Read from register (CIA 1)
204 */
205
206 uint8 MOS6526_1::ReadRegister(uint16 adr)
207 {
208 switch (adr) {
209 case 0x00: {
210 uint8 ret = pra | ~ddra, tst = (prb | ~ddrb) & Joystick1;
211 if (!(tst & 0x01)) ret &= RevMatrix[0]; // AND all active columns
212 if (!(tst & 0x02)) ret &= RevMatrix[1];
213 if (!(tst & 0x04)) ret &= RevMatrix[2];
214 if (!(tst & 0x08)) ret &= RevMatrix[3];
215 if (!(tst & 0x10)) ret &= RevMatrix[4];
216 if (!(tst & 0x20)) ret &= RevMatrix[5];
217 if (!(tst & 0x40)) ret &= RevMatrix[6];
218 if (!(tst & 0x80)) ret &= RevMatrix[7];
219 return ret & Joystick2;
220 }
221 case 0x01: {
222 uint8 ret = ~ddrb, tst = (pra | ~ddra) & Joystick2;
223 if (!(tst & 0x01)) ret &= KeyMatrix[0]; // AND all active rows
224 if (!(tst & 0x02)) ret &= KeyMatrix[1];
225 if (!(tst & 0x04)) ret &= KeyMatrix[2];
226 if (!(tst & 0x08)) ret &= KeyMatrix[3];
227 if (!(tst & 0x10)) ret &= KeyMatrix[4];
228 if (!(tst & 0x20)) ret &= KeyMatrix[5];
229 if (!(tst & 0x40)) ret &= KeyMatrix[6];
230 if (!(tst & 0x80)) ret &= KeyMatrix[7];
231 return (ret | (prb & ddrb)) & Joystick1;
232 }
233 case 0x02: return ddra;
234 case 0x03: return ddrb;
235 case 0x04: return ta;
236 case 0x05: return ta >> 8;
237 case 0x06: return tb;
238 case 0x07: return tb >> 8;
239 case 0x08: tod_halt = false; return tod_10ths;
240 case 0x09: return tod_sec;
241 case 0x0a: return tod_min;
242 case 0x0b: tod_halt = true; return tod_hr;
243 case 0x0c: return sdr;
244 case 0x0d: {
245 uint8 ret = icr; // Read and clear ICR
246 icr = 0;
247 the_cpu->ClearCIAIRQ(); // Clear IRQ
248 return ret;
249 }
250 case 0x0e: return cra;
251 case 0x0f: return crb;
252 }
253 return 0; // Can't happen
254 }
255
256
257 /*
258 * Read from register (CIA 2)
259 */
260
261 uint8 MOS6526_2::ReadRegister(uint16 adr)
262 {
263 switch (adr) {
264 case 0x00:
265 return (pra | ~ddra) & 0x3f
266 | IECLines & the_cpu_1541->IECLines;
267 case 0x01: return prb | ~ddrb;
268 case 0x02: return ddra;
269 case 0x03: return ddrb;
270 case 0x04: return ta;
271 case 0x05: return ta >> 8;
272 case 0x06: return tb;
273 case 0x07: return tb >> 8;
274 case 0x08: tod_halt = false; return tod_10ths;
275 case 0x09: return tod_sec;
276 case 0x0a: return tod_min;
277 case 0x0b: tod_halt = true; return tod_hr;
278 case 0x0c: return sdr;
279 case 0x0d: {
280 uint8 ret = icr; // Read and clear ICR
281 icr = 0;
282 the_cpu->ClearNMI();
283 return ret;
284 }
285 case 0x0e: return cra;
286 case 0x0f: return crb;
287 }
288 return 0; // Can't happen
289 }
290
291
292 /*
293 * Write to register (CIA 1)
294 */
295
296 // Write to port B, check for lightpen interrupt
297 inline void MOS6526_1::check_lp(void)
298 {
299 if ((prb | ~ddrb) & 0x10 != prev_lp)
300 the_vic->TriggerLightpen();
301 prev_lp = (prb | ~ddrb) & 0x10;
302 }
303
304 void MOS6526_1::WriteRegister(uint16 adr, uint8 byte)
305 {
306 switch (adr) {
307 case 0x0: pra = byte; break;
308 case 0x1:
309 prb = byte;
310 check_lp();
311 break;
312 case 0x2: ddra = byte; break;
313 case 0x3:
314 ddrb = byte;
315 check_lp();
316 break;
317
318 case 0x4: latcha = (latcha & 0xff00) | byte; break;
319 case 0x5:
320 latcha = (latcha & 0xff) | (byte << 8);
321 if (!(cra & 1)) // Reload timer if stopped
322 ta = latcha;
323 break;
324
325 case 0x6: latchb = (latchb & 0xff00) | byte; break;
326 case 0x7:
327 latchb = (latchb & 0xff) | (byte << 8);
328 if (!(crb & 1)) // Reload timer if stopped
329 tb = latchb;
330 break;
331
332 case 0x8:
333 if (crb & 0x80)
334 alm_10ths = byte & 0x0f;
335 else
336 tod_10ths = byte & 0x0f;
337 break;
338 case 0x9:
339 if (crb & 0x80)
340 alm_sec = byte & 0x7f;
341 else
342 tod_sec = byte & 0x7f;
343 break;
344 case 0xa:
345 if (crb & 0x80)
346 alm_min = byte & 0x7f;
347 else
348 tod_min = byte & 0x7f;
349 break;
350 case 0xb:
351 if (crb & 0x80)
352 alm_hr = byte & 0x9f;
353 else
354 tod_hr = byte & 0x9f;
355 break;
356
357 case 0xc:
358 sdr = byte;
359 TriggerInterrupt(8); // Fake SDR interrupt for programs that need it
360 break;
361
362 case 0xd:
363 if (byte & 0x80)
364 int_mask |= byte & 0x7f;
365 else
366 int_mask &= ~byte;
367 if (icr & int_mask & 0x1f) { // Trigger IRQ if pending
368 icr |= 0x80;
369 the_cpu->TriggerCIAIRQ();
370 }
371 break;
372
373 case 0xe:
374 has_new_cra = true; // Delay write by 1 cycle
375 new_cra = byte;
376 ta_cnt_phi2 = ((byte & 0x20) == 0x00);
377 break;
378
379 case 0xf:
380 has_new_crb = true; // Delay write by 1 cycle
381 new_crb = byte;
382 tb_cnt_phi2 = ((byte & 0x60) == 0x00);
383 tb_cnt_ta = ((byte & 0x60) == 0x40);
384 break;
385 }
386 }
387
388
389 /*
390 * Write to register (CIA 2)
391 */
392
393 void MOS6526_2::WriteRegister(uint16 adr, uint8 byte)
394 {
395 switch (adr) {
396 case 0x0:{
397 pra = byte;
398 the_vic->ChangedVA(~(pra | ~ddra) & 3);
399 uint8 old_lines = IECLines;
400 IECLines = (~byte << 2) & 0x80 // DATA
401 | (~byte << 2) & 0x40 // CLK
402 | (~byte << 1) & 0x10; // ATN
403 if ((IECLines ^ old_lines) & 0x10) { // ATN changed
404 the_cpu_1541->NewATNState();
405 if (old_lines & 0x10) // ATN 1->0
406 the_cpu_1541->IECInterrupt();
407 }
408 break;
409 }
410 case 0x1: prb = byte; break;
411
412 case 0x2:
413 ddra = byte;
414 the_vic->ChangedVA(~(pra | ~ddra) & 3);
415 break;
416 case 0x3: ddrb = byte; break;
417
418 case 0x4: latcha = (latcha & 0xff00) | byte; break;
419 case 0x5:
420 latcha = (latcha & 0xff) | (byte << 8);
421 if (!(cra & 1)) // Reload timer if stopped
422 ta = latcha;
423 break;
424
425 case 0x6: latchb = (latchb & 0xff00) | byte; break;
426 case 0x7:
427 latchb = (latchb & 0xff) | (byte << 8);
428 if (!(crb & 1)) // Reload timer if stopped
429 tb = latchb;
430 break;
431
432 case 0x8:
433 if (crb & 0x80)
434 alm_10ths = byte & 0x0f;
435 else
436 tod_10ths = byte & 0x0f;
437 break;
438 case 0x9:
439 if (crb & 0x80)
440 alm_sec = byte & 0x7f;
441 else
442 tod_sec = byte & 0x7f;
443 break;
444 case 0xa:
445 if (crb & 0x80)
446 alm_min = byte & 0x7f;
447 else
448 tod_min = byte & 0x7f;
449 break;
450 case 0xb:
451 if (crb & 0x80)
452 alm_hr = byte & 0x9f;
453 else
454 tod_hr = byte & 0x9f;
455 break;
456
457 case 0xc:
458 sdr = byte;
459 TriggerInterrupt(8); // Fake SDR interrupt for programs that need it
460 break;
461
462 case 0xd:
463 if (byte & 0x80)
464 int_mask |= byte & 0x7f;
465 else
466 int_mask &= ~byte;
467 if (icr & int_mask & 0x1f) { // Trigger NMI if pending
468 icr |= 0x80;
469 the_cpu->TriggerNMI();
470 }
471 break;
472
473 case 0xe:
474 has_new_cra = true; // Delay write by 1 cycle
475 new_cra = byte;
476 ta_cnt_phi2 = ((byte & 0x20) == 0x00);
477 break;
478
479 case 0xf:
480 has_new_crb = true; // Delay write by 1 cycle
481 new_crb = byte;
482 tb_cnt_phi2 = ((byte & 0x60) == 0x00);
483 tb_cnt_ta = ((byte & 0x60) == 0x40);
484 break;
485 }
486 }
487
488
489 /*
490 * Emulate CIA for one cycle/raster line
491 */
492
493 void MOS6526::EmulateCycle(void)
494 {
495 bool ta_underflow = false;
496
497 // Timer A state machine
498 switch (ta_state) {
499 case T_WAIT_THEN_COUNT:
500 ta_state = T_COUNT; // fall through
501 case T_STOP:
502 goto ta_idle;
503 case T_LOAD_THEN_STOP:
504 ta_state = T_STOP;
505 ta = latcha; // Reload timer
506 goto ta_idle;
507 case T_LOAD_THEN_COUNT:
508 ta_state = T_COUNT;
509 ta = latcha; // Reload timer
510 goto ta_idle;
511 case T_LOAD_THEN_WAIT_THEN_COUNT:
512 ta_state = T_WAIT_THEN_COUNT;
513 if (ta == 1)
514 goto ta_interrupt; // Interrupt if timer == 1
515 else {
516 ta = latcha; // Reload timer
517 goto ta_idle;
518 }
519 case T_COUNT:
520 goto ta_count;
521 case T_COUNT_THEN_STOP:
522 ta_state = T_STOP;
523 goto ta_count;
524 }
525
526 // Count timer A
527 ta_count:
528 if (ta_cnt_phi2)
529 if (!ta || !--ta) { // Decrement timer, underflow?
530 if (ta_state != T_STOP) {
531 ta_interrupt:
532 ta = latcha; // Reload timer
533 ta_irq_next_cycle = true; // Trigger interrupt in next cycle
534 icr |= 1; // But set ICR bit now
535
536 if (cra & 8) { // One-shot?
537 cra &= 0xfe; // Yes, stop timer
538 new_cra &= 0xfe;
539 ta_state = T_LOAD_THEN_STOP; // Reload in next cycle
540 } else
541 ta_state = T_LOAD_THEN_COUNT; // No, delay one cycle (and reload)
542 }
543 ta_underflow = true;
544 }
545
546 // Delayed write to CRA?
547 ta_idle:
548 if (has_new_cra) {
549 switch (ta_state) {
550 case T_STOP:
551 case T_LOAD_THEN_STOP:
552 if (new_cra & 1) { // Timer started, wasn't running
553 if (new_cra & 0x10) // Force load
554 ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
555 else // No force load
556 ta_state = T_WAIT_THEN_COUNT;
557 } else { // Timer stopped, was already stopped
558 if (new_cra & 0x10) // Force load
559 ta_state = T_LOAD_THEN_STOP;
560 }
561 break;
562 case T_COUNT:
563 if (new_cra & 1) { // Timer started, was already running
564 if (new_cra & 0x10) // Force load
565 ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
566 } else { // Timer stopped, was running
567 if (new_cra & 0x10) // Force load
568 ta_state = T_LOAD_THEN_STOP;
569 else // No force load
570 ta_state = T_COUNT_THEN_STOP;
571 }
572 break;
573 case T_LOAD_THEN_COUNT:
574 case T_WAIT_THEN_COUNT:
575 if (new_cra & 1) {
576 if (new_cra & 8) { // One-shot?
577 new_cra &= 0xfe; // Yes, stop timer
578 ta_state = T_STOP;
579 } else if (new_cra & 0x10) // Force load
580 ta_state = T_LOAD_THEN_WAIT_THEN_COUNT;
581 } else {
582 ta_state = T_STOP;
583 }
584 break;
585 }
586 cra = new_cra & 0xef;
587 has_new_cra = false;
588 }
589
590 // Timer B state machine
591 switch (tb_state) {
592 case T_WAIT_THEN_COUNT:
593 tb_state = T_COUNT; // fall through
594 case T_STOP:
595 goto tb_idle;
596 case T_LOAD_THEN_STOP:
597 tb_state = T_STOP;
598 tb = latchb; // Reload timer
599 goto tb_idle;
600 case T_LOAD_THEN_COUNT:
601 tb_state = T_COUNT;
602 tb = latchb; // Reload timer
603 goto tb_idle;
604 case T_LOAD_THEN_WAIT_THEN_COUNT:
605 tb_state = T_WAIT_THEN_COUNT;
606 if (tb == 1)
607 goto tb_interrupt; // Interrupt if timer == 1
608 else {
609 tb = latchb; // Reload timer
610 goto tb_idle;
611 }
612 case T_COUNT:
613 goto tb_count;
614 case T_COUNT_THEN_STOP:
615 tb_state = T_STOP;
616 goto tb_count;
617 }
618
619 // Count timer B
620 tb_count:
621 if (tb_cnt_phi2 || (tb_cnt_ta && ta_underflow))
622 if (!tb || !--tb) { // Decrement timer, underflow?
623 if (tb_state != T_STOP) {
624 tb_interrupt:
625 tb = latchb; // Reload timer
626 tb_irq_next_cycle = true; // Trigger interrupt in next cycle
627 icr |= 2; // But set ICR bit now
628
629 if (crb & 8) { // One-shot?
630 crb &= 0xfe; // Yes, stop timer
631 new_crb &= 0xfe;
632 tb_state = T_LOAD_THEN_STOP; // Reload in next cycle
633 } else
634 tb_state = T_LOAD_THEN_COUNT; // No, delay one cycle (and reload)
635 }
636 }
637
638 // Delayed write to CRB?
639 tb_idle:
640 if (has_new_crb) {
641 switch (tb_state) {
642 case T_STOP:
643 case T_LOAD_THEN_STOP:
644 if (new_crb & 1) { // Timer started, wasn't running
645 if (new_crb & 0x10) // Force load
646 tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
647 else // No force load
648 tb_state = T_WAIT_THEN_COUNT;
649 } else { // Timer stopped, was already stopped
650 if (new_crb & 0x10) // Force load
651 tb_state = T_LOAD_THEN_STOP;
652 }
653 break;
654 case T_COUNT:
655 if (new_crb & 1) { // Timer started, was already running
656 if (new_crb & 0x10) // Force load
657 tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
658 } else { // Timer stopped, was running
659 if (new_crb & 0x10) // Force load
660 tb_state = T_LOAD_THEN_STOP;
661 else // No force load
662 tb_state = T_COUNT_THEN_STOP;
663 }
664 break;
665 case T_LOAD_THEN_COUNT:
666 case T_WAIT_THEN_COUNT:
667 if (new_crb & 1) {
668 if (new_crb & 8) { // One-shot?
669 new_crb &= 0xfe; // Yes, stop timer
670 tb_state = T_STOP;
671 } else if (new_crb & 0x10) // Force load
672 tb_state = T_LOAD_THEN_WAIT_THEN_COUNT;
673 } else {
674 tb_state = T_STOP;
675 }
676 break;
677 }
678 crb = new_crb & 0xef;
679 has_new_crb = false;
680 }
681 }
682
683
684 /*
685 * Count CIA TOD clock (called during VBlank)
686 */
687
688 void MOS6526::CountTOD(void)
689 {
690 uint8 lo, hi;
691
692 // Decrement frequency divider
693 if (tod_divider)
694 tod_divider--;
695 else {
696
697 // Reload divider according to 50/60 Hz flag
698 if (cra & 0x80)
699 tod_divider = 4;
700 else
701 tod_divider = 5;
702
703 // 1/10 seconds
704 tod_10ths++;
705 if (tod_10ths > 9) {
706 tod_10ths = 0;
707
708 // Seconds
709 lo = (tod_sec & 0x0f) + 1;
710 hi = tod_sec >> 4;
711 if (lo > 9) {
712 lo = 0;
713 hi++;
714 }
715 if (hi > 5) {
716 tod_sec = 0;
717
718 // Minutes
719 lo = (tod_min & 0x0f) + 1;
720 hi = tod_min >> 4;
721 if (lo > 9) {
722 lo = 0;
723 hi++;
724 }
725 if (hi > 5) {
726 tod_min = 0;
727
728 // Hours
729 lo = (tod_hr & 0x0f) + 1;
730 hi = (tod_hr >> 4) & 1;
731 tod_hr &= 0x80; // Keep AM/PM flag
732 if (lo > 9) {
733 lo = 0;
734 hi++;
735 }
736 tod_hr |= (hi << 4) | lo;
737 if ((tod_hr & 0x1f) > 0x11)
738 tod_hr = tod_hr & 0x80 ^ 0x80;
739 } else
740 tod_min = (hi << 4) | lo;
741 } else
742 tod_sec = (hi << 4) | lo;
743 }
744
745 // Alarm time reached? Trigger interrupt if enabled
746 if (tod_10ths == alm_10ths && tod_sec == alm_sec &&
747 tod_min == alm_min && tod_hr == alm_hr)
748 TriggerInterrupt(4);
749 }
750 }
751
752
753 /*
754 * Trigger IRQ (CIA 1)
755 */
756
757 void MOS6526_1::TriggerInterrupt(int bit)
758 {
759 icr |= bit;
760 if (int_mask & bit) {
761 icr |= 0x80;
762 the_cpu->TriggerCIAIRQ();
763 }
764 }
765
766
767 /*
768 * Trigger NMI (CIA 2)
769 */
770
771 void MOS6526_2::TriggerInterrupt(int bit)
772 {
773 icr |= bit;
774 if (int_mask & bit) {
775 icr |= 0x80;
776 the_cpu->TriggerNMI();
777 }
778 }