00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef C64_H
00024 #define C64_H
00025
00026 #include "Banks/Bank.h"
00027 #include "Banks/IOBank.h"
00028 #include "Banks/ColorRAMBank.h"
00029 #include "Banks/DisconnectedBusBank.h"
00030 #include "Banks/SidBank.h"
00031 #include "Banks/ExtraSidBank.h"
00032
00033 #include "sidplayfp/c64/c64env.h"
00034 #include "sidplayfp/c64/c64cpu.h"
00035 #include "sidplayfp/c64/c64cia.h"
00036 #include "sidplayfp/c64/c64vic.h"
00037 #include "sidplayfp/c64/mmu.h"
00038
00039
00040 #ifdef HAVE_CONFIG_H
00041 # include "config.h"
00042 #endif
00043
00044
00045 #ifdef PC64_TESTSUITE
00046 class testEnv
00047 {
00048 public:
00049 virtual ~testEnv() {}
00050 virtual void load(const char *) =0;
00051 };
00052 #endif
00053
00065 class c64: private c64env
00066 {
00067 public:
00069 static const unsigned int MAX_SIDS = 2;
00070
00071 public:
00072 typedef enum
00073 {
00074 PAL_B = 0
00075 ,NTSC_M
00076 ,OLD_NTSC_M
00077 ,PAL_N
00078 } model_t;
00079
00080 private:
00082 double m_cpuFreq;
00083
00085 int irqCount;
00086
00088 bool oldBAState;
00089
00091 EventScheduler m_scheduler;
00092
00094 c64cpu cpu;
00095
00097 c64cia1 cia1;
00098
00100 c64cia2 cia2;
00101
00103 c64vic vic;
00104
00106 ColorRAMBank colorRAMBank;
00107
00109 SidBank sidBank;
00110
00112 ExtraSidBank extraSidBank;
00113
00115 DisconnectedBusBank disconnectedBusBank;
00116
00118 IOBank ioBank;
00119
00121 MMU mmu;
00122
00123 private:
00124 static double getCpuFreq(model_t model);
00125
00126 private:
00133 uint8_t cpuRead(uint_least16_t addr) { return mmu.cpuRead(addr); }
00134
00141 void cpuWrite(uint_least16_t addr, uint8_t data) { mmu.cpuWrite(addr, data); }
00142
00150 inline void interruptIRQ(bool state);
00151
00157 inline void interruptNMI() { cpu.triggerNMI (); }
00158
00162 inline void interruptRST() { cpu.triggerRST (); }
00163
00171 inline void setBA(bool state);
00172
00173 inline void lightpen() { vic.lightpen (); }
00174
00175 #ifdef PC64_TESTSUITE
00176 testEnv *m_env;
00177
00178 void loadFile(const char *file)
00179 {
00180 m_env->load(file);
00181 }
00182 #endif
00183
00184 void resetIoBank();
00185
00186 public:
00187 c64();
00188 ~c64() {}
00189
00190 #ifdef PC64_TESTSUITE
00191 void setTestEnv(testEnv *env)
00192 {
00193 m_env = env;
00194 }
00195 #endif
00196
00203 EventScheduler *getEventScheduler() { return &m_scheduler; }
00204 const EventScheduler &getEventScheduler() const { return m_scheduler; }
00206
00207 void debug(bool enable, FILE *out) { cpu.debug (enable, out); }
00208
00209 void reset();
00210 void resetCpu() { cpu.reset(); }
00211
00215 void setModel(model_t model);
00216
00217 void setRoms(const uint8_t* kernal, const uint8_t* basic, const uint8_t* character)
00218 {
00219 mmu.setRoms(kernal, basic, character);
00220 }
00221
00227 double getMainCpuSpeed() const { return m_cpuFreq; }
00228
00235 void setSid(unsigned int i, sidemu *s);
00236
00243 sidemu *getSid(unsigned int i) const;
00244
00254 void setSecondSIDAddress(int sidChipBase2);
00255
00260 const char* cpuCredits () const { return cpu.credits(); }
00261 const char* ciaCredits () const { return cia1.credits(); }
00262 const char* vicCredits () const { return vic.credits(); }
00264
00265 sidmemory *getMemInterface() { return &mmu; }
00266
00267 uint_least16_t getCia1TimerA() const { return cia1.getTimerA(); }
00268 };
00269
00270 void c64::interruptIRQ (bool state)
00271 {
00272 if (state)
00273 {
00274 if (irqCount == 0)
00275 cpu.triggerIRQ ();
00276
00277 irqCount ++;
00278 }
00279 else
00280 {
00281 irqCount --;
00282 if (irqCount == 0)
00283 cpu.clearIRQ ();
00284 }
00285 }
00286
00287 void c64::setBA (bool state)
00288 {
00289
00290 if ((state ^ oldBAState) == false)
00291 return;
00292
00293 oldBAState = state;
00294
00295
00296 cpu.setRDY (state);
00297 }
00298
00299 #endif // C64_H