summaryrefslogtreecommitdiff
path: root/sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h
diff options
context:
space:
mode:
Diffstat (limited to 'sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h')
-rw-r--r--sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h288
1 files changed, 288 insertions, 0 deletions
diff --git a/sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h b/sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h
new file mode 100644
index 00000000..98171d73
--- /dev/null
+++ b/sid/sidplay-libs-2.1.0/libsidplay/src/xsid/xsid.h
@@ -0,0 +1,288 @@
+/***************************************************************************
+ xsid.h - Support for Playsids Extended
+ Registers
+ -------------------
+ begin : Tue Jun 20 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: xsid.h,v $
+ * Revision 1.21 2002/09/23 19:42:52 s_a_white
+ * Fixed intel compiler warnings.
+ *
+ * Revision 1.20 2002/07/17 19:18:17 s_a_white
+ * Changed bad #if to #ifdef
+ *
+ * Revision 1.19 2002/02/21 20:26:13 s_a_white
+ * Nolonger default to Galway Mode when Noise samples init incorrectly. Fixes
+ * VARIOUS/S-Z/Zyron/Bouncy_Balls.sid (HVSC).
+ *
+ * Revision 1.18 2002/02/17 16:34:39 s_a_white
+ * New reset interface
+ *
+ * Revision 1.17 2001/11/16 19:22:04 s_a_white
+ * Removed compiler warning for unused parameter.
+ *
+ * Revision 1.16 2001/10/18 22:36:16 s_a_white
+ * GCC3 fixes.
+ *
+ * Revision 1.15 2001/07/14 16:48:35 s_a_white
+ * Sync with sidbuilder class project.
+ *
+ * Revision 1.14 2001/07/14 12:59:39 s_a_white
+ * XSID effeciency increased. Now uses new component classes and event
+ * generation.
+ *
+ * Revision 1.13 2001/04/20 22:21:06 s_a_white
+ * inlined updateSidData0x18.
+ *
+ * Revision 1.12 2001/03/25 19:51:23 s_a_white
+ * Performance update.
+ *
+ * Revision 1.11 2001/03/19 23:40:46 s_a_white
+ * Better support for global debug.
+ *
+ * Revision 1.10 2001/03/09 22:27:13 s_a_white
+ * Speed optimisation update.
+ *
+ * Revision 1.9 2001/03/01 23:45:58 s_a_white
+ * Combined both through sid and non-through sid modes. Can be selected
+ * at runtime now.
+ *
+ * Revision 1.8 2001/02/21 21:46:34 s_a_white
+ * 0x1d = 0 now fixed. Limit checking on sid volume. This helps us determine
+ * even better what the sample offset should be (fixes Skate and Die).
+ *
+ * Revision 1.7 2001/02/07 21:02:30 s_a_white
+ * Supported for delaying samples for frame simulation. New alogarithm to
+ * better guess original tunes volume when playing samples.
+ *
+ * Revision 1.6 2000/12/12 22:51:01 s_a_white
+ * Bug Fix #122033.
+ *
+ ***************************************************************************/
+
+/*
+Effectively there is only 1 channel, which can either perform Galway Noise
+or Sampling. However, to achieve all the effects on a C64, 2 sampling
+channels are required. No divide by 2 is required and is compensated for
+automatically in the C64 machine code.
+
+Confirmed by Warren Pilkington using the tune Turbo Outrun:
+A new sample must interrupt an existing sample running on the same channel.
+
+Confirmed by Michael Schwendt and Antonia Vera using the tune Game Over:
+A Galway Sample or Noise sequence cannot interrupt any other. However
+the last of these new requested sequences will be played after the current
+sequence ends.
+
+Lastly playing samples through the SIDs volume is not as clean as playing
+them on their own channel. Playing through the SID will effect the volume
+of the other channels and this will be most noticable at low frequencies.
+These effects are however present in the original SID music.
+
+Some SIDs put values directly into the volume register. Others play samples
+with respect to the current volume. We can't for definate know which the author
+has chosen originally. We must just make a guess based on what the volume
+is initially at the start of a sample sequence and from the details xSID has been
+programmed with.
+*/
+
+#ifndef _xsid_h_
+#define _xsid_h_
+
+#include "config.h"
+#include "sidbuilder.h"
+#include "event.h"
+
+// XSID configuration settings
+//#define XSID_DEBUG 1
+
+// Support global debug option
+#ifdef DEBUG
+# ifndef XSID_DEBUG
+# define XSID_DEBUG DEBUG
+# endif
+#endif
+
+#ifdef XSID_DEBUG
+# include <stdio.h>
+#endif
+
+class XSID;
+class channel
+{
+private:
+ // General
+ const char * const m_name;
+ EventContext &m_context;
+ XSID &m_xsid;
+ friend class XSID;
+
+ class SampleEvent: public Event
+ {
+ private:
+ channel &m_ch;
+ void event (void) { m_ch.sampleClock (); }
+
+ public:
+ SampleEvent (channel *ch)
+ :Event("xSID Sample"),
+ m_ch(*ch) {}
+ } sampleEvent;
+ friend class SampleEvent;
+
+ class GalwayEvent: public Event
+ {
+ private:
+ channel &m_ch;
+ void event (void) { m_ch.galwayClock (); }
+
+ public:
+ GalwayEvent (channel *ch)
+ :Event("xSID Galway"),
+ m_ch(*ch) {}
+ } galwayEvent;
+ friend class GalwayEvent;
+
+ uint8_t reg[0x10];
+ enum {FM_NONE = 0, FM_HUELS, FM_GALWAY} mode;
+ bool active;
+ uint_least16_t address;
+ uint_least16_t cycleCount; // Counts to zero and triggers!
+ uint_least8_t volShift;
+ uint_least8_t sampleLimit;
+ int8_t sample;
+
+ // Sample Section
+ uint_least8_t samRepeat;
+ uint_least8_t samScale;
+ enum {SO_LOWHIGH = 0, SO_HIGHLOW = 1};
+ uint_least8_t samOrder;
+ uint_least8_t samNibble;
+ uint_least16_t samEndAddr;
+ uint_least16_t samRepeatAddr;
+ uint_least16_t samPeriod;
+
+ // Galway Section
+ uint_least8_t galTones;
+ uint_least8_t galInitLength;
+ uint_least8_t galLength;
+ uint_least8_t galVolume;
+ uint_least8_t galLoopWait;
+ uint_least8_t galNullWait;
+
+ // For Debugging
+ event_clock_t cycles;
+ event_clock_t outputs;
+
+private:
+ channel (const char * const name, EventContext *context, XSID *xsid);
+ void free (void);
+ void silence (void);
+ void sampleInit (void);
+ void sampleClock (void);
+ void galwayInit (void);
+ void galwayClock (void);
+
+ // Compress address to not leave so many spaces
+ uint_least8_t convertAddr(uint_least8_t addr)
+ { return (((addr) & 0x3) | ((addr) >> 3) & 0x0c); }
+
+ void reset (void);
+ uint8_t read (uint_least8_t addr)
+ { return reg[convertAddr (addr)]; }
+ void write (uint_least8_t addr, uint8_t data)
+ { reg[convertAddr (addr)] = data; }
+ int8_t output (void);
+ bool isGalway (void)
+ { return mode == FM_GALWAY; }
+
+ uint_least8_t limit (void)
+ { return sampleLimit; }
+
+ inline void checkForInit (void);
+ inline int8_t sampleCalculate (void);
+ inline void galwayTonePeriod (void);
+
+ // Used to indicate if channel is running
+ operator bool() const { return (active); }
+};
+
+
+class XSID: public sidemu, private Event
+{
+ friend class channel;
+
+private:
+ channel ch4;
+ channel ch5;
+ bool muted;
+ bool suppressed;
+ static const char *credit;
+
+ uint8_t sidData0x18;
+ bool _sidSamples;
+ int8_t sampleOffset;
+ static const int8_t sampleConvertTable[16];
+ bool wasRunning;
+
+private:
+ void event (void);
+ void checkForInit (channel *ch);
+ inline void setSidData0x18 (void);
+ inline void recallSidData0x18 (void);
+ int8_t sampleOutput (void);
+ void sampleOffsetCalc (void);
+ virtual uint8_t readMemByte (uint_least16_t addr) = 0;
+ virtual void writeMemByte (uint8_t data) = 0;
+
+public:
+ XSID (EventContext *context);
+
+ // Standard calls
+ void reset () { sidemu::reset (); }
+ void reset (uint8_t);
+ uint8_t read (uint_least8_t) { return 0; }
+ void write (uint_least8_t, uint8_t) { ; }
+ const char *credits (void) {return credit;}
+
+ // Specialist calls
+ uint8_t read (uint_least16_t) { return 0; }
+ void write (uint_least16_t addr, uint8_t data);
+ int_least32_t output (uint_least8_t bits = 16);
+ void mute (bool enable);
+ bool isMuted (void) { return muted; }
+ void suppress (bool enable);
+
+ void sidSamples (bool enable)
+ { _sidSamples = enable; }
+ // Return whether we care it was changed.
+ bool storeSidData0x18 (uint8_t data);
+};
+
+
+/***************************************************************************
+ * Inline functions
+ **************************************************************************/
+
+inline int_least32_t XSID::output (uint_least8_t bits)
+{
+ int_least32_t sample;
+ if (_sidSamples || muted)
+ return 0;
+ sample = sampleConvertTable[sampleOutput () + 8];
+ return sample << (bits - 8);
+}
+
+#endif // _xsid_h_