00001
00002
00003
00004
00005
00006
00007 #ifndef _CPU_1541_H
00008 #define _CPU_1541_H
00009
00010 #include "CIA.h"
00011 #include "C64.h"
00012
00013
00014
00015 #ifndef FRODO_SC
00016 #ifndef PC_IS_POINTER
00017 #define PC_IS_POINTER 1
00018 #endif
00019 #endif
00020
00021
00022 #ifndef PRECISE_CPU_CYCLES
00023 #define PRECISE_CPU_CYCLES 0
00024 #endif
00025
00026
00027
00028 enum {
00029 INT_VIA1IRQ,
00030 INT_VIA2IRQ,
00031 INT_IECIRQ
00032
00033 };
00034
00035
00036 class C64;
00037 class Job1541;
00038 class C64Display;
00039 struct MOS6502State;
00040
00041
00042
00043 class MOS6502_1541 {
00044 public:
00045 MOS6502_1541(C64 *c64, Job1541 *job, C64Display *disp, uint8 *Ram, uint8 *Rom);
00046 ~MOS6502_1541();
00047
00048 #ifdef FRODO_SC
00049 void EmulateCycle(void);
00050 #else
00051 int EmulateLine(int cycles_left);
00052 #endif
00053 void Reset(void);
00054 void AsyncReset(void);
00055 void GetState(MOS6502State *s);
00056 void SetState(MOS6502State *s);
00057 uint8 ExtReadByte(uint16 adr);
00058 void ExtWriteByte(uint16 adr, uint8 byte);
00059 void CountVIATimers(int cycles);
00060 void NewATNState(void);
00061 void IECInterrupt(void);
00062 void TriggerJobIRQ(void);
00063 bool InterruptEnabled(void);
00064
00065 MOS6526_2 *TheCIA2;
00066
00067 uint8 IECLines;
00068 bool Idle;
00069
00070 private:
00071 uint8 read_byte(uint16 adr);
00072 uint8 read_byte_io(uint16 adr);
00073 uint16 read_word(uint16 adr);
00074 void write_byte(uint16 adr, uint8 byte);
00075 void write_byte_io(uint16 adr, uint8 byte);
00076
00077 uint8 read_zp(uint16 adr);
00078 uint16 read_zp_word(uint16 adr);
00079 void write_zp(uint16 adr, uint8 byte);
00080
00081 void jump(uint16 adr);
00082 void illegal_op(uint8 op, uint16 at);
00083 void illegal_jump(uint16 at, uint16 to);
00084
00085 void do_adc(uint8 byte);
00086 void do_sbc(uint8 byte);
00087
00088 uint8 *ram;
00089 uint8 *rom;
00090 C64 *the_c64;
00091 C64Display *the_display;
00092 Job1541 *the_job;
00093
00094 union {
00095 uint8 intr[4];
00096 unsigned long intr_any;
00097 } interrupt;
00098
00099 uint8 n_flag, z_flag;
00100 bool v_flag, d_flag, i_flag, c_flag;
00101 uint8 a, x, y, sp;
00102 #if PC_IS_POINTER
00103 uint8 *pc, *pc_base;
00104 #else
00105 uint16 pc;
00106 #endif
00107
00108 #ifdef FRODO_SC
00109 uint32 first_irq_cycle;
00110
00111 uint8 state, op;
00112 uint16 ar, ar2;
00113 uint8 rdbuf;
00114 uint8 ddr, pr;
00115 #else
00116 int borrowed_cycles;
00117 #endif
00118
00119 uint8 via1_pra;
00120 uint8 via1_ddra;
00121 uint8 via1_prb;
00122 uint8 via1_ddrb;
00123 uint16 via1_t1c;
00124 uint16 via1_t1l;
00125 uint16 via1_t2c;
00126 uint16 via1_t2l;
00127 uint8 via1_sr;
00128 uint8 via1_acr;
00129 uint8 via1_pcr;
00130 uint8 via1_ifr;
00131 uint8 via1_ier;
00132
00133 uint8 via2_pra;
00134 uint8 via2_ddra;
00135 uint8 via2_prb;
00136 uint8 via2_ddrb;
00137 uint16 via2_t1c;
00138 uint16 via2_t1l;
00139 uint16 via2_t2c;
00140 uint16 via2_t2l;
00141 uint8 via2_sr;
00142 uint8 via2_acr;
00143 uint8 via2_pcr;
00144 uint8 via2_ifr;
00145 uint8 via2_ier;
00146 };
00147
00148
00149 struct MOS6502State {
00150 uint8 a, x, y;
00151 uint8 p;
00152 uint16 pc, sp;
00153
00154 uint8 intr[4];
00155 bool instruction_complete;
00156 bool idle;
00157
00158 uint8 via1_pra;
00159 uint8 via1_ddra;
00160 uint8 via1_prb;
00161 uint8 via1_ddrb;
00162 uint16 via1_t1c;
00163 uint16 via1_t1l;
00164 uint16 via1_t2c;
00165 uint16 via1_t2l;
00166 uint8 via1_sr;
00167 uint8 via1_acr;
00168 uint8 via1_pcr;
00169 uint8 via1_ifr;
00170 uint8 via1_ier;
00171
00172 uint8 via2_pra;
00173 uint8 via2_ddra;
00174 uint8 via2_prb;
00175 uint8 via2_ddrb;
00176 uint16 via2_t1c;
00177 uint16 via2_t1l;
00178 uint16 via2_t2c;
00179 uint16 via2_t2l;
00180 uint8 via2_sr;
00181 uint8 via2_acr;
00182 uint8 via2_pcr;
00183 uint8 via2_ifr;
00184 uint8 via2_ier;
00185 };
00186
00187
00188
00189
00190
00191
00192
00193 #ifdef FRODO_SC
00194 inline void MOS6502_1541::TriggerJobIRQ(void)
00195 {
00196 if (!(interrupt.intr[INT_VIA2IRQ]))
00197 first_irq_cycle = the_c64->CycleCounter;
00198 interrupt.intr[INT_VIA2IRQ] = true;
00199 Idle = false;
00200 }
00201 #else
00202 inline void MOS6502_1541::TriggerJobIRQ(void)
00203 {
00204 interrupt.intr[INT_VIA2IRQ] = true;
00205 Idle = false;
00206 }
00207 #endif
00208
00209
00210
00211
00212
00213
00214 inline void MOS6502_1541::CountVIATimers(int cycles)
00215 {
00216 unsigned long tmp;
00217
00218 via1_t1c = tmp = via1_t1c - cycles;
00219 if (tmp > 0xffff) {
00220 if (via1_acr & 0x40)
00221 via1_t1c = via1_t1l;
00222 via1_ifr |= 0x40;
00223 }
00224
00225 if (!(via1_acr & 0x20)) {
00226 via1_t2c = tmp = via1_t2c - cycles;
00227 if (tmp > 0xffff)
00228 via1_ifr |= 0x20;
00229 }
00230
00231 via2_t1c = tmp = via2_t1c - cycles;
00232 if (tmp > 0xffff) {
00233 if (via2_acr & 0x40)
00234 via2_t1c = via2_t1l;
00235 via2_ifr |= 0x40;
00236 if (via2_ier & 0x40)
00237 TriggerJobIRQ();
00238 }
00239
00240 if (!(via2_acr & 0x20)) {
00241 via2_t2c = tmp = via2_t2c - cycles;
00242 if (tmp > 0xffff)
00243 via2_ifr |= 0x20;
00244 }
00245 }
00246
00247
00248
00249
00250
00251
00252 inline void MOS6502_1541::NewATNState(void)
00253 {
00254 uint8 byte = ~via1_prb & via1_ddrb;
00255 IECLines = (byte << 6) & ((~byte ^ TheCIA2->IECLines) << 3) & 0x80
00256 | (byte << 3) & 0x40;
00257 }
00258
00259
00260
00261
00262
00263
00264 inline void MOS6502_1541::IECInterrupt(void)
00265 {
00266 ram[0x7c] = 1;
00267
00268
00269 Idle = false;
00270 }
00271
00272
00273
00274
00275
00276
00277 inline bool MOS6502_1541::InterruptEnabled(void)
00278 {
00279 return !i_flag;
00280 }
00281
00282 #endif