Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

CIA.h

Go to the documentation of this file.
00001 /*
00002  *  CIA.h - 6526 emulation
00003  *
00004  *  Frodo (C) 1994-1997 Christian Bauer
00005  */
00006 
00007 #ifndef _CIA_H
00008 #define _CIA_H
00009 
00010 #include "Prefs.h"
00011 
00012 
00013 class MOS6510;
00014 class MOS6502_1541;
00015 class MOS6569;
00016 struct MOS6526State;
00017 
00018 
00019 class MOS6526 {
00020 public:
00021         MOS6526(MOS6510 *CPU);
00022 
00023         void Reset(void);
00024         void GetState(MOS6526State *cs);
00025         void SetState(MOS6526State *cs);
00026 #ifdef FRODO_SC
00027         void CheckIRQs(void);
00028         void EmulateCycle(void);
00029 #else
00030         void EmulateLine(int cycles);
00031 #endif
00032         void CountTOD(void);
00033         virtual void TriggerInterrupt(int bit)=0;
00034 
00035 protected:
00036         MOS6510 *the_cpu;       // Pointer to 6510
00037 
00038         uint8 pra, prb, ddra, ddrb;
00039 
00040         uint16 ta, tb, latcha, latchb;
00041 
00042         uint8 tod_10ths, tod_sec, tod_min, tod_hr;
00043         uint8 alm_10ths, alm_sec, alm_min, alm_hr;
00044 
00045         uint8 sdr, icr, cra, crb;
00046         uint8 int_mask;
00047 
00048         int tod_divider;        // TOD frequency divider
00049 
00050         bool tod_halt,          // Flag: TOD halted
00051                  ta_cnt_phi2,   // Flag: Timer A is counting Phi 2
00052                  tb_cnt_phi2,   // Flag: Timer B is counting Phi 2
00053              tb_cnt_ta;         // Flag: Timer B is counting underflows of Timer A
00054 
00055 #ifdef FRODO_SC
00056         bool ta_irq_next_cycle,         // Flag: Trigger TA IRQ in next cycle
00057                  tb_irq_next_cycle,             // Flag: Trigger TB IRQ in next cycle
00058                  has_new_cra,                   // Flag: New value for CRA pending
00059                  has_new_crb;                   // Flag: New value for CRB pending
00060         char ta_state, tb_state;        // Timer A/B states
00061         uint8 new_cra, new_crb;         // New values for CRA/CRB
00062 #endif
00063         Prefs* ThePrefs;
00064 };
00065 
00066 
00067 class MOS6526_1 : public MOS6526 {
00068 public:
00069         MOS6526_1(MOS6510 *CPU, MOS6569 *VIC);
00070         virtual ~MOS6526_1();
00071 
00072         void Reset(void);
00073         uint8 ReadRegister(uint16 adr);
00074         void WriteRegister(uint16 adr, uint8 byte);
00075         virtual void TriggerInterrupt(int bit);
00076 
00077         uint8 KeyMatrix[8];     // C64 keyboard matrix, 1 bit/key (0: key down, 1: key up)
00078         uint8 RevMatrix[8];     // Reversed keyboard matrix
00079 
00080         uint8 Joystick1;        // Joystick 1 AND value
00081         uint8 Joystick2;        // Joystick 2 AND value
00082 
00083 private:
00084         void check_lp(void);
00085 
00086         MOS6569 *the_vic;
00087 
00088         uint8 prev_lp;          // Previous state of LP line (bit 4)
00089 };
00090 
00091 
00092 class MOS6526_2 : public MOS6526{
00093 public:
00094         MOS6526_2(MOS6510 *CPU, MOS6569 *VIC, MOS6502_1541 *CPU1541);
00095         virtual ~MOS6526_2();
00096 
00097         void Reset(void);
00098         uint8 ReadRegister(uint16 adr);
00099         void WriteRegister(uint16 adr, uint8 byte);
00100         virtual void TriggerInterrupt(int bit);
00101 
00102         uint8 IECLines;         // State of IEC lines (bit 7 - DATA, bit 6 - CLK, bit 4 - ATN)
00103 
00104 private:
00105         MOS6569 *the_vic;
00106         MOS6502_1541 *the_cpu_1541;
00107 };
00108 
00109 
00110 // CIA state
00111 struct MOS6526State {
00112         uint8 pra;
00113         uint8 ddra;
00114         uint8 prb;
00115         uint8 ddrb;
00116         uint8 ta_lo;
00117         uint8 ta_hi;
00118         uint8 tb_lo;
00119         uint8 tb_hi;
00120         uint8 tod_10ths;
00121         uint8 tod_sec;
00122         uint8 tod_min;
00123         uint8 tod_hr;
00124         uint8 sdr;
00125         uint8 int_data;         // Pending interrupts
00126         uint8 cra;
00127         uint8 crb;
00128                                                 // Additional registers
00129         uint16 latcha;          // Timer latches
00130         uint16 latchb;
00131         uint8 alm_10ths;        // Alarm time
00132         uint8 alm_sec;
00133         uint8 alm_min;
00134         uint8 alm_hr;
00135         uint8 int_mask;         // Enabled interrupts
00136 };
00137 
00138 
00139 /*
00140  *  Emulate CIA for one cycle/raster line
00141  */
00142 
00143 #ifdef FRODO_SC
00144 inline void MOS6526::CheckIRQs(void)
00145 {
00146         // Trigger pending interrupts
00147         if (ta_irq_next_cycle) {
00148                 ta_irq_next_cycle = false;
00149                 TriggerInterrupt(1);
00150         }
00151         if (tb_irq_next_cycle) {
00152                 tb_irq_next_cycle = false;
00153                 TriggerInterrupt(2);
00154         }
00155 }
00156 #else
00157 inline void MOS6526::EmulateLine(int cycles)
00158 {
00159         unsigned long tmp;
00160 
00161         // Timer A
00162         if (ta_cnt_phi2) {
00163                 ta = tmp = ta - cycles;         // Decrement timer
00164 
00165                 if (tmp > 0xffff) {                     // Underflow?
00166                         ta = latcha;                    // Reload timer
00167 
00168                         if (cra & 8) {                  // One-shot?
00169                                 cra &= 0xfe;
00170                                 ta_cnt_phi2 = false;
00171                         }
00172                         TriggerInterrupt(1);
00173                         if (tb_cnt_ta) {                // Timer B counting underflows of Timer A?
00174                                 tb = tmp = tb - 1;      // tmp = --tb doesn't work
00175                                 if (tmp > 0xffff) goto tb_underflow;
00176                         }
00177                 }
00178         }
00179 
00180         // Timer B
00181         if (tb_cnt_phi2) {
00182                 tb = tmp = tb - cycles;         // Decrement timer
00183 
00184                 if (tmp > 0xffff) {                     // Underflow?
00185 tb_underflow:
00186                         tb = latchb;
00187 
00188                         if (crb & 8) {                  // One-shot?
00189                                 crb &= 0xfe;
00190                                 tb_cnt_phi2 = false;
00191                                 tb_cnt_ta = false;
00192                         }
00193                         TriggerInterrupt(2);
00194                 }
00195         }
00196 }
00197 #endif
00198 
00199 #endif

Generated on Tue Feb 8 04:07:27 2005 for E32frodo by doxygen 1.3.3