00001
00002
00003
00004
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;
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;
00049
00050 bool tod_halt,
00051 ta_cnt_phi2,
00052 tb_cnt_phi2,
00053 tb_cnt_ta;
00054
00055 #ifdef FRODO_SC
00056 bool ta_irq_next_cycle,
00057 tb_irq_next_cycle,
00058 has_new_cra,
00059 has_new_crb;
00060 char ta_state, tb_state;
00061 uint8 new_cra, new_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];
00078 uint8 RevMatrix[8];
00079
00080 uint8 Joystick1;
00081 uint8 Joystick2;
00082
00083 private:
00084 void check_lp(void);
00085
00086 MOS6569 *the_vic;
00087
00088 uint8 prev_lp;
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;
00103
00104 private:
00105 MOS6569 *the_vic;
00106 MOS6502_1541 *the_cpu_1541;
00107 };
00108
00109
00110
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;
00126 uint8 cra;
00127 uint8 crb;
00128
00129 uint16 latcha;
00130 uint16 latchb;
00131 uint8 alm_10ths;
00132 uint8 alm_sec;
00133 uint8 alm_min;
00134 uint8 alm_hr;
00135 uint8 int_mask;
00136 };
00137
00138
00139
00140
00141
00142
00143 #ifdef FRODO_SC
00144 inline void MOS6526::CheckIRQs(void)
00145 {
00146
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
00162 if (ta_cnt_phi2) {
00163 ta = tmp = ta - cycles;
00164
00165 if (tmp > 0xffff) {
00166 ta = latcha;
00167
00168 if (cra & 8) {
00169 cra &= 0xfe;
00170 ta_cnt_phi2 = false;
00171 }
00172 TriggerInterrupt(1);
00173 if (tb_cnt_ta) {
00174 tb = tmp = tb - 1;
00175 if (tmp > 0xffff) goto tb_underflow;
00176 }
00177 }
00178 }
00179
00180
00181 if (tb_cnt_phi2) {
00182 tb = tmp = tb - cycles;
00183
00184 if (tmp > 0xffff) {
00185 tb_underflow:
00186 tb = latchb;
00187
00188 if (crb & 8) {
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