summaryrefslogtreecommitdiff
path: root/plugins/sid/sidplay-libs/libsidplay/src/player.h
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/sid/sidplay-libs/libsidplay/src/player.h')
-rw-r--r--plugins/sid/sidplay-libs/libsidplay/src/player.h434
1 files changed, 434 insertions, 0 deletions
diff --git a/plugins/sid/sidplay-libs/libsidplay/src/player.h b/plugins/sid/sidplay-libs/libsidplay/src/player.h
new file mode 100644
index 00000000..7c0a024c
--- /dev/null
+++ b/plugins/sid/sidplay-libs/libsidplay/src/player.h
@@ -0,0 +1,434 @@
+ /***************************************************************************
+ player.h - description
+ -------------------
+ begin : Fri Jun 9 2000
+ copyright : (C) 2000 by Simon White
+ email : s_a_white@email.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/***************************************************************************
+ * $Log: player.h,v $
+ * Revision 1.39 2002/12/03 23:25:53 s_a_white
+ * Prevent PSID digis from playing in real C64 mode.
+ *
+ * Revision 1.38 2002/11/27 00:16:51 s_a_white
+ * Make sure driver info gets reset and exported properly.
+ *
+ * Revision 1.37 2002/11/20 21:44:34 s_a_white
+ * Initial support for external DMA to steal cycles away from the CPU.
+ *
+ * Revision 1.36 2002/11/19 22:55:50 s_a_white
+ * PSIDv2NG/RSID changes to deal with spec updates for recommended
+ * implementation.
+ *
+ * Revision 1.35 2002/11/01 17:36:01 s_a_white
+ * Frame based support for old sidplay1 modes.
+ *
+ * Revision 1.34 2002/10/02 19:45:23 s_a_white
+ * RSID support.
+ *
+ * Revision 1.33 2002/09/12 21:01:31 s_a_white
+ * Added support for simulating the random delay before the user loads a
+ * program on a real C64.
+ *
+ * Revision 1.32 2002/09/09 18:01:30 s_a_white
+ * Prevent m_info driver details getting modified when C64 crashes.
+ *
+ * Revision 1.31 2002/07/21 19:39:41 s_a_white
+ * Proper error handling of reloc info overlapping load image.
+ *
+ * Revision 1.30 2002/07/20 08:34:52 s_a_white
+ * Remove unnecessary and pointless conts.
+ *
+ * Revision 1.29 2002/07/17 21:48:10 s_a_white
+ * PSIDv2NG reloc exclude region extension.
+ *
+ * Revision 1.28 2002/04/14 21:46:50 s_a_white
+ * PlaySID reads fixed to come from RAM only.
+ *
+ * Revision 1.27 2002/03/12 18:43:59 s_a_white
+ * Tidy up handling of envReset on illegal CPU instructions.
+ *
+ * Revision 1.26 2002/03/03 22:01:58 s_a_white
+ * New clock speed & sid model interface.
+ *
+ * Revision 1.25 2002/01/29 21:50:33 s_a_white
+ * Auto switching to a better emulation mode. m_tuneInfo reloaded after a
+ * config. Initial code added to support more than two sids.
+ *
+ * Revision 1.24 2002/01/28 19:32:01 s_a_white
+ * PSID sample improvements.
+ *
+ * Revision 1.23 2001/12/13 08:28:08 s_a_white
+ * Added namespace support to fix problems with xsidplay.
+ *
+ * Revision 1.22 2001/10/18 22:34:04 s_a_white
+ * GCC3 fixes.
+ *
+ * Revision 1.21 2001/10/02 18:26:36 s_a_white
+ * Removed ReSID support and updated for new scheduler.
+ *
+ * Revision 1.20 2001/09/20 19:32:39 s_a_white
+ * Support for a null sid emulation to use when a builder create call fails.
+ *
+ * Revision 1.19 2001/09/17 19:02:38 s_a_white
+ * Now uses fixed point maths for sample output and rtc.
+ *
+ * Revision 1.18 2001/09/01 11:15:46 s_a_white
+ * Fixes sidplay1 environment modes.
+ *
+ * Revision 1.17 2001/08/10 21:01:06 s_a_white
+ * Fixed RTC initialisation order warning.
+ *
+ * Revision 1.16 2001/08/10 20:03:19 s_a_white
+ * Added RTC reset.
+ *
+ * Revision 1.15 2001/07/25 17:01:13 s_a_white
+ * Support for new configuration interface.
+ *
+ * Revision 1.14 2001/07/14 16:46:16 s_a_white
+ * Sync with sidbuilder class project.
+ *
+ * Revision 1.13 2001/07/14 12:50:58 s_a_white
+ * Support for credits and debuging. External filter selection removed. RTC
+ * and samples obtained in a more efficient way. Support for component
+ * and sidbuilder classes.
+ *
+ * Revision 1.12 2001/04/23 17:09:56 s_a_white
+ * Fixed video speed selection using unforced/forced and NTSC clockSpeeds.
+ *
+ * Revision 1.11 2001/03/22 22:45:20 s_a_white
+ * Re-ordered initialisations to match defintions.
+ *
+ * Revision 1.10 2001/03/21 23:28:12 s_a_white
+ * Support new component names.
+ *
+ * Revision 1.9 2001/03/21 22:32:55 s_a_white
+ * Filter redefinition support. VIC & NMI support added.
+ *
+ * Revision 1.8 2001/03/08 22:48:33 s_a_white
+ * Sid reset on player destruction removed. Now handled locally by the sids.
+ *
+ * Revision 1.7 2001/03/01 23:46:37 s_a_white
+ * Support for sample mode to be selected at runtime.
+ *
+ * Revision 1.6 2001/02/28 18:52:55 s_a_white
+ * Removed initBank* related stuff.
+ *
+ * Revision 1.5 2001/02/21 21:41:51 s_a_white
+ * Added seperate ram bank to hold C64 player.
+ *
+ * Revision 1.4 2001/02/07 20:56:46 s_a_white
+ * Samples now delayed until end of simulated frame.
+ *
+ * Revision 1.3 2001/01/23 21:26:28 s_a_white
+ * Only way to load a tune now is by passing in a sidtune object. This is
+ * required for songlength database support.
+ *
+ * Revision 1.2 2001/01/07 15:58:37 s_a_white
+ * SID2_LIB_API now becomes a core define (SID_API).
+ *
+ * Revision 1.1 2000/12/12 19:15:40 s_a_white
+ * Renamed from sidplayer
+ *
+ ***************************************************************************/
+
+#ifndef _player_h_
+#define _player_h_
+
+#include <string.h>
+
+#include "config.h"
+#include "sidplay2.h"
+#include "sidenv.h"
+#include "c64env.h"
+#include "c64/c64xsid.h"
+#include "c64/c64cia.h"
+#include "c64/c64vic.h"
+
+#include "mos6510/mos6510.h"
+#include "sid6526/sid6526.h"
+#include "nullsid.h"
+#define SID2_MAX_SIDS 2
+
+SIDPLAY2_NAMESPACE_START
+
+class Player: private C64Environment, c64env
+{
+private:
+ static const double CLOCK_FREQ_NTSC;
+ static const double CLOCK_FREQ_PAL;
+ static const double VIC_FREQ_PAL;
+ static const double VIC_FREQ_NTSC;
+
+ static const char *TXT_PAL_VBI;
+ static const char *TXT_PAL_VBI_FIXED;
+ static const char *TXT_PAL_CIA;
+ static const char *TXT_PAL_UNKNOWN;
+ static const char *TXT_NTSC_VBI;
+ static const char *TXT_NTSC_VBI_FIXED;
+ static const char *TXT_NTSC_CIA;
+ static const char *TXT_NTSC_UNKNOWN;
+ static const char *TXT_NA;
+
+ static const char *ERR_CONF_WHILST_ACTIVE;
+ static const char *ERR_UNSUPPORTED_FREQ;
+ static const char *ERR_UNSUPPORTED_PRECISION;
+ static const char *ERR_MEM_ALLOC;
+ static const char *ERR_UNSUPPORTED_MODE;
+ static const char *credit[10]; // 10 credits max
+
+ static const char *ERR_PSIDDRV_NO_SPACE;
+ static const char *ERR_PSIDDRV_RELOC;
+
+ EventScheduler m_scheduler;
+
+ //SID6510 cpu(6510, "Main CPU");
+ SID6510 sid6510;
+ MOS6510 mos6510;
+ MOS6510 *cpu;
+ // Sid objects to use.
+ NullSID nullsid;
+ c64xsid xsid;
+ c64cia1 cia;
+ c64cia2 cia2;
+ SID6526 sid6526;
+ c64vic vic;
+ sidemu *sid[SID2_MAX_SIDS];
+
+ class EventMixer: public Event
+ {
+ private:
+ Player &m_player;
+ void event (void) { m_player.mixer (); }
+
+ public:
+ EventMixer (Player *player)
+ :Event("Mixer"),
+ m_player(*player) {}
+ } mixerEvent;
+ friend class EventMixer;
+
+ class EventRTC: public Event
+ {
+ private:
+ EventContext &m_eventContext;
+ event_clock_t m_seconds;
+ event_clock_t m_period;
+ event_clock_t m_clk;
+
+ void event (void)
+ { // Fixed point 25.7 (approx 2 dp)
+ event_clock_t cycles;
+ m_clk += m_period;
+ cycles = m_clk >> 7;
+ m_clk &= 0x7F;
+ m_seconds++;
+ m_eventContext.schedule (this, cycles);
+ }
+
+ public:
+ EventRTC (EventContext *context)
+ :Event("RTC"),
+ m_eventContext(*context),
+ m_seconds(0)
+ {;}
+
+ event_clock_t getTime () const {return m_seconds;}
+
+ void reset (void)
+ { // Fixed point 25.7
+ m_seconds = 0;
+ m_clk = m_period & 0x7F;
+ m_eventContext.schedule (this, m_period >> 7);
+ }
+
+ void clock (float64_t period)
+ { // Fixed point 25.7
+ m_period = (event_clock_t) (period / 10.0 * (float64_t) (1 << 7));
+ reset ();
+ }
+ } rtc;
+
+ // User Configuration Settings
+ SidTuneInfo m_tuneInfo;
+ SidTune *m_tune;
+ uint8_t *m_ram, *m_rom;
+ sid2_info_t m_info;
+ sid2_config_t m_cfg;
+
+ const char *m_errorString;
+ float64_t m_fastForwardFactor;
+ uint_least32_t m_mileage;
+ int_least32_t m_leftVolume;
+ int_least32_t m_rightVolume;
+ volatile sid2_player_t m_playerState;
+ volatile bool m_running;
+ int m_rand;
+
+ // Mixer settings
+ event_clock_t m_sampleClock;
+ event_clock_t m_samplePeriod;
+ uint_least32_t m_sampleCount;
+ uint_least32_t m_sampleIndex;
+ char *m_sampleBuffer;
+
+ // C64 environment settings
+ uint8_t m_bankReg;
+ uint8_t m_playBank;
+ uint_least16_t m_sidAddress[2];
+
+ // temp stuff -------------
+ bool isKernal;
+ bool isBasic;
+ bool isIO;
+ inline void evalBankSelect (uint8_t data);
+ void c64_initialise (void);
+ // ------------------------
+
+private:
+ float64_t clockSpeed (sid2_clock_t clock, sid2_clock_t defaultClock,
+ bool forced);
+ int environment (sid2_env_t env);
+ void fakeIRQ (void);
+ int initialise (void);
+ void nextSequence (void);
+ void mixer (void);
+ void mixerReset (void);
+ void mileageCorrect (void);
+ int sidCreate (sidbuilder *builder, sid2_model_t model,
+ sid2_model_t defaultModel);
+ void sidSamples (bool enable);
+ void reset ();
+ uint8_t iomap (uint_least16_t addr);
+
+ uint8_t readMemByte_player (uint_least16_t addr);
+ uint8_t readMemByte_plain (uint_least16_t addr);
+ uint8_t readMemByte_io (uint_least16_t addr);
+ uint8_t readMemByte_sidplaytp (uint_least16_t addr);
+ uint8_t readMemByte_sidplaybs (uint_least16_t addr);
+ void writeMemByte_plain (uint_least16_t addr, uint8_t data);
+ void writeMemByte_playsid (uint_least16_t addr, uint8_t data);
+ void writeMemByte_sidplay (uint_least16_t addr, uint8_t data);
+
+ // Use pointers to please requirements of all the provided
+ // environments.
+ uint8_t (Player::*m_readMemByte) (uint_least16_t);
+ void (Player::*m_writeMemByte) (uint_least16_t, uint8_t);
+ uint8_t (Player::*m_readMemDataByte)(uint_least16_t);
+
+ uint8_t readMemRamByte (uint_least16_t addr)
+ { return m_ram[addr]; }
+
+ // Environment Function entry Points
+ void envReset (bool safe);
+ inline void envReset (void) { envReset (true); }
+ uint8_t envReadMemByte (uint_least16_t addr);
+ inline void envWriteMemByte (uint_least16_t addr, uint8_t data);
+ inline bool envCheckBankJump (uint_least16_t addr);
+ inline uint8_t envReadMemDataByte (uint_least16_t addr);
+ inline void envSleep (void);
+
+ void envLoadFile (char *file)
+ {
+ char name[0x100] = "e:/emulators/c64/games/prgs/";
+ strcat (name, file);
+ strcat (name, ".sid");
+ m_tune->load (name);
+ stop ();
+ }
+
+ // Rev 2.0.3 Added - New Mixer Routines
+ uint_least32_t (Player::*output) (char *buffer);
+
+ // Rev 2.0.4 (saw) - Added to reduce code size
+ int_least32_t monoOutGenericLeftIn (uint_least8_t bits);
+ int_least32_t monoOutGenericStereoIn (uint_least8_t bits);
+ int_least32_t monoOutGenericRightIn (uint_least8_t bits);
+
+ // 8 bit output
+ uint_least32_t monoOut8MonoIn (char *buffer);
+ uint_least32_t monoOut8StereoIn (char *buffer);
+ uint_least32_t monoOut8StereoRIn (char *buffer);
+ uint_least32_t stereoOut8MonoIn (char *buffer);
+ uint_least32_t stereoOut8StereoIn (char *buffer);
+
+ // Rev 2.0.4 (jp) - Added 16 bit support
+ uint_least32_t monoOut16MonoIn (char *buffer);
+ uint_least32_t monoOut16StereoIn (char *buffer);
+ uint_least32_t monoOut16StereoRIn (char *buffer);
+ uint_least32_t stereoOut16MonoIn (char *buffer);
+ uint_least32_t stereoOut16StereoIn (char *buffer);
+
+ void interruptIRQ (bool state);
+ void interruptNMI (void);
+ void interruptRST (void);
+ void signalBA (bool state) { cpu->rdySignal (state); }
+ void signalAEC (bool state) { cpu->aecSignal (state); }
+
+ // PSID driver
+ int psidDrvInstall (SidTuneInfo &tuneInfo, sid2_info_t &info);
+ void psidRelocAddr (SidTuneInfo &tuneInfo, int startp, int endp);
+
+public:
+ Player ();
+
+ const sid2_config_t &config (void) const { return m_cfg; }
+ const sid2_info_t &info (void) const { return m_info; }
+
+ int config (const sid2_config_t &cfg);
+ int fastForward (uint percent);
+ int load (SidTune *tune);
+ uint_least8_t mileage (void) const { return m_mileage + time(); }
+ void pause (void);
+ uint_least32_t play (void *buffer, uint_least32_t length);
+ sid2_player_t state (void) const { return m_playerState; }
+ void stop (void);
+ uint_least32_t time (void) const {return rtc.getTime (); }
+ void debug (bool enable) { cpu->debug (enable); }
+ const char *error (void) const { return m_errorString; }
+};
+
+inline void Player::envSleep (void)
+{
+ if (m_info.environment != sid2_envR)
+ { // Start the sample sequence
+ xsid.suppress (false);
+ xsid.suppress (true);
+ }
+}
+
+inline void Player::interruptIRQ (bool state)
+{
+ if (state)
+ {
+ if (m_info.environment == sid2_envR)
+ cpu->triggerIRQ ();
+ else
+ fakeIRQ ();
+ }
+ else
+ cpu->clearIRQ ();
+}
+
+inline void Player::interruptNMI ()
+{
+ cpu->triggerNMI ();
+}
+
+inline void Player::interruptRST ()
+{
+ stop ();
+}
+
+SIDPLAY2_NAMESPACE_STOP
+
+#endif // _player_h_