ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/Frodo4/Src/CIA_SC.cpp
(Generate patch)

Comparing Frodo4/Src/CIA_SC.cpp (file contents):
Revision 1.1 by cebix, 2003-07-01T17:09:43Z vs.
Revision 1.8 by cebix, 2010-04-25T12:02:13Z

# Line 1 | Line 1
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
# Line 58 | Line 58 | enum {
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  
# Line 93 | Line 93 | void MOS6526::Reset(void)
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  
# Line 199 | Line 201 | void MOS6526::SetState(MOS6526State *cs)
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  
# Line 227 | Line 259 | uint8 MOS6526_1::ReadRegister(uint16 adr
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;
# Line 263 | Line 301 | uint8 MOS6526_2::ReadRegister(uint16 adr
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;
# Line 363 | Line 409 | void MOS6526_1::WriteRegister(uint16 adr
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                          }
# Line 531 | Line 577 | 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 +                                ta_toggle = !ta_toggle; // Toggle PB6 output
581  
582                                  if (cra & 8) {                  // One-shot?
583                                          cra &= 0xfe;            // Yes, stop timer
# Line 549 | Line 596 | ta_idle:
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
# Line 599 | Line 647 | ta_idle:
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)
# Line 624 | Line 672 | 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 +                                tb_toggle = !tb_toggle; // Toggle PB7 output
676  
677                                  if (crb & 8) {                  // One-shot?
678                                          crb &= 0xfe;            // Yes, stop timer
# Line 641 | Line 690 | tb_idle:
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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines