libsidplayfp 1.0.3
c64.h
00001 /*
00002  * This file is part of libsidplayfp, a SID player engine.
00003  *
00004  * Copyright 2011-2013 Leandro Nini <drfiemost@users.sourceforge.net>
00005  * Copyright 2007-2010 Antti Lankila
00006  * Copyright 2000 Simon White
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
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     /* only react to changes in state */
00290     if ((state ^ oldBAState) == false)
00291         return;
00292 
00293     oldBAState = state;
00294 
00295     /* Signal changes in BA to interested parties */
00296     cpu.setRDY (state);
00297 }
00298 
00299 #endif // C64_H