Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

SID_epoc.cpp

Go to the documentation of this file.
00001 /*
00002  *  SID.cpp - 6581 emulation
00003  *
00004  *  Frodo (C) 1994-1997 Christian Bauer
00005  *
00006 
00007  *
00008  * Incompatibilities:
00009  * ------------------
00010  *
00011  *  - Lots of empirically determined constants in the filter calculations
00012  *  - Voice 3 cannot be muted
00013  */
00014 
00015 #include "sysdeps.h"
00016 #include <math.h>
00017 
00018 #include "SID.h"
00019 #include "Prefs.h"
00020 
00021 #ifdef __BEOS__
00022 #include <MediaKit.h>
00023 #endif
00024 
00025 #ifdef AMIGA
00026 #include <exec/types.h>
00027 #include <utility/hooks.h>
00028 #include <devices/ahi.h>
00029 #define USE_FIXPOINT_MATHS
00030 #define FIXPOINT_PREC 16        // number of fractional bits used in fixpoint representation
00031 #define PRECOMPUTE_RESONANCE
00032 #define ldSINTAB 9                      // size of sinus table (0 to 90 degrees)
00033 #endif
00034 
00035 #include "C64.h"
00036 
00037 #ifdef SUN
00038 extern "C" {
00039         #include <sys/audioio.h>
00040 }
00041 #endif
00042 
00043 #ifdef __hpux
00044 extern "C" {
00045         #include <sys/audio.h>
00046 }
00047 #endif
00048 
00049 #ifdef __mac__
00050 #include <Sound.h>
00051 #define M_PI 3.14159265358979323846
00052 #endif
00053 
00054 #ifdef WIN32
00055 class DigitalPlayer;
00056 #endif
00057 
00058 #ifdef __riscos__
00059 #include "ROLib.h"
00060 # ifndef M_PI
00061 # define M_PI 3.14159265358979323846
00062 # endif
00063 #define USE_FIXPOINT_MATHS
00064 #define FIXPOINT_PREC 16        // number of fractional bits used in fixpoint representation
00065 #define PRECOMPUTE_RESONANCE
00066 #define ldSINTAB 9                      // size of sinus table (0 to 90 degrees)
00067 #endif
00068 
00069 #ifdef __SYMBIAN32__
00070 #define USE_FIXPOINT_MATHS
00071 //#define FIXPOINT_PREC 16      // number of fractional bits used in fixpoint representation
00072 //#define PRECOMPUTE_RESONANCE
00073 //#define ldSINTAB 9                    // size of sinus table (0 to 90 degrees)
00074 #define SOUND_BUF_SIZE (0x1000)
00075 
00076 #include "VIC.h"
00077 #include <d32snd.h>
00078 
00079 #endif // __SYMBIAN32__
00080 
00081 #ifdef USE_FIXPOINT_MATHS
00082 #include "FixPoint.i"
00083 #endif
00084 
00085 
00086 /*
00087  *  Resonance frequency polynomials
00088  */
00089 
00090 #define CALC_RESONANCE_LP(f) (227.755\
00091                                 - 1.7635 * f\
00092                                 - 0.0176385 * f * f\
00093                                 + 0.00333484 * f * f * f\
00094                                 - 9.05683E-6 * f * f * f * f)
00095 
00096 #define CALC_RESONANCE_HP(f) (366.374\
00097                                 - 14.0052 * f\
00098                                 + 0.603212 * f * f\
00099                                 - 0.000880196 * f * f * f)
00100 
00101 
00102 
00103 
00107 MOS6581::MOS6581(C64 *c64) : the_c64(c64), ThePrefs(c64->ThePrefs)
00108 {
00109         __CHECK_NULL(c64);
00110 
00111         the_renderer = NULL;
00112         for (int i=0; i<32; i++)
00113                 regs[i] = 0;
00114 
00115         // Open the renderer
00116         open_close_renderer(SIDTYPE_NONE, ThePrefs.SIDType);
00117 
00118         CTOR(MOS6581);
00119 }
00120 
00121 
00125 MOS6581::~MOS6581()
00126 {
00127         // Close the renderer
00128         open_close_renderer(ThePrefs.SIDType, SIDTYPE_NONE);
00129 
00130         DTOR(MOS6581);
00131 }
00132 
00133 
00137 void MOS6581::Reset(void)
00138 {
00139         for (int i=0; i<32; i++)
00140                 regs[i] = 0;
00141         last_sid_byte = 0;
00142 
00143         // Reset the renderer
00144         if (the_renderer != NULL)
00145                 the_renderer->Reset();
00146 
00147         ELOG1(_L8("SID reset\n"));
00148 }
00149 
00150 
00151 /*
00152  *  Preferences may have changed
00153  */
00154 
00155 void MOS6581::NewPrefs(Prefs *prefs)
00156 {
00157         open_close_renderer(ThePrefs.SIDType, prefs->SIDType);
00158         if (the_renderer != NULL)
00159                 the_renderer->NewPrefs(prefs);
00160 }
00161 
00162 
00163 /*
00164  *  Pause sound output
00165  */
00166 
00167 void MOS6581::PauseSound(void)
00168 {
00169         if (the_renderer != NULL)
00170                 the_renderer->Pause();
00171 }
00172 
00173 
00174 /*
00175  *  Resume sound output
00176  */
00177 
00178 void MOS6581::ResumeSound(void)
00179 {
00180         if (the_renderer != NULL)
00181                 the_renderer->Resume();
00182 }
00183 
00184 
00185 /*
00186  *  Get SID state
00187  */
00188 
00189 void MOS6581::GetState(MOS6581State *ss)
00190 {
00191         ss->freq_lo_1 = regs[0];
00192         ss->freq_hi_1 = regs[1];
00193         ss->pw_lo_1 = regs[2];
00194         ss->pw_hi_1 = regs[3];
00195         ss->ctrl_1 = regs[4];
00196         ss->AD_1 = regs[5];
00197         ss->SR_1 = regs[6];
00198 
00199         ss->freq_lo_2 = regs[7];
00200         ss->freq_hi_2 = regs[8];
00201         ss->pw_lo_2 = regs[9];
00202         ss->pw_hi_2 = regs[10];
00203         ss->ctrl_2 = regs[11];
00204         ss->AD_2 = regs[12];
00205         ss->SR_2 = regs[13];
00206 
00207         ss->freq_lo_3 = regs[14];
00208         ss->freq_hi_3 = regs[15];
00209         ss->pw_lo_3 = regs[16];
00210         ss->pw_hi_3 = regs[17];
00211         ss->ctrl_3 = regs[18];
00212         ss->AD_3 = regs[19];
00213         ss->SR_3 = regs[20];
00214 
00215         ss->fc_lo = regs[21];
00216         ss->fc_hi = regs[22];
00217         ss->res_filt = regs[23];
00218         ss->mode_vol = regs[24];
00219 
00220         ss->pot_x = 0xff;
00221         ss->pot_y = 0xff;
00222         ss->osc_3 = 0;
00223         ss->env_3 = 0;
00224 }
00225 
00226 
00227 /*
00228  *  Restore SID state
00229  */
00230 
00231 void MOS6581::SetState(MOS6581State *ss)
00232 {
00233         regs[0] = ss->freq_lo_1;
00234         regs[1] = ss->freq_hi_1;
00235         regs[2] = ss->pw_lo_1;
00236         regs[3] = ss->pw_hi_1;
00237         regs[4] = ss->ctrl_1;
00238         regs[5] = ss->AD_1;
00239         regs[6] = ss->SR_1;
00240 
00241         regs[7] = ss->freq_lo_2;
00242         regs[8] = ss->freq_hi_2;
00243         regs[9] = ss->pw_lo_2;
00244         regs[10] = ss->pw_hi_2;
00245         regs[11] = ss->ctrl_2;
00246         regs[12] = ss->AD_2;
00247         regs[13] = ss->SR_2;
00248 
00249         regs[14] = ss->freq_lo_3;
00250         regs[15] = ss->freq_hi_3;
00251         regs[16] = ss->pw_lo_3;
00252         regs[17] = ss->pw_hi_3;
00253         regs[18] = ss->ctrl_3;
00254         regs[19] = ss->AD_3;
00255         regs[20] = ss->SR_3;
00256 
00257         regs[21] = ss->fc_lo;
00258         regs[22] = ss->fc_hi;
00259         regs[23] = ss->res_filt;
00260         regs[24] = ss->mode_vol;
00261 
00262         // Stuff the new register values into the renderer
00263         if (the_renderer != NULL)
00264                 for (int i=0; i<25; i++)
00265                         the_renderer->WriteRegister(i, regs[i]);
00266 }
00267 
00268 
00273 #if defined(AMIGA) || defined(__riscos__)
00274 const uint32 SAMPLE_FREQ = 22050;       // Sample output frequency in Hz
00275 #else
00276 const uint32 SAMPLE_FREQ = 44100;       // Sample output frequency in Hz
00277 #endif
00278 const uint32 SID_FREQ = 985248;         // SID frequency in Hz
00279 const uint32 CALC_FREQ = 50;                    // Frequency at which calc_buffer is called in Hz (should be 50Hz)
00280 const uint32 SID_CYCLES = SID_FREQ/SAMPLE_FREQ; // # of SID clocks per sample frame
00281 const int SAMPLE_BUF_SIZE = 0x138*2;// Size of buffer for sampled voice (double buffered)
00282 
00283 // SID waveforms (some of them :-)
00284 enum {
00285         WAVE_NONE,
00286         WAVE_TRI,
00287         WAVE_SAW,
00288         WAVE_TRISAW,
00289         WAVE_RECT,
00290         WAVE_TRIRECT,
00291         WAVE_SAWRECT,
00292         WAVE_TRISAWRECT,
00293         WAVE_NOISE
00294 };
00295 
00296 // EG states
00297 enum {
00298         EG_IDLE,
00299         EG_ATTACK,
00300         EG_DECAY,
00301         EG_RELEASE
00302 };
00303 
00304 // Filter types
00305 enum {
00306         FILT_NONE,
00307         FILT_LP,
00308         FILT_BP,
00309         FILT_LPBP,
00310         FILT_HP,
00311         FILT_NOTCH,
00312         FILT_HPBP,
00313         FILT_ALL
00314 };
00315 
00316 // Structure for one voice
00317 struct DRVoice {
00318         int wave;               // Selected waveform
00319         int eg_state;   // Current state of EG
00320         DRVoice *mod_by;        // Voice that modulates this one
00321         DRVoice *mod_to;        // Voice that is modulated by this one
00322 
00323         uint32 count;   // Counter for waveform generator, 8.16 fixed
00324         uint32 add;             // Added to counter in every frame
00325 
00326         uint16 freq;            // SID frequency value
00327         uint16 pw;              // SID pulse-width value
00328 
00329         uint32 a_add;   // EG parameters
00330         uint32 d_sub;
00331         uint32 s_level;
00332         uint32 r_sub;
00333         uint32 eg_level;        // Current EG level, 8.16 fixed
00334 
00335         uint32 noise;   // Last noise generator output value
00336 
00337         bool gate;              // EG gate bit
00338         bool ring;              // Ring modulation bit
00339         bool test;              // Test bit
00340         bool filter;    // Flag: Voice filtered
00341 
00342                                         // The following bit is set for the modulating
00343                                         // voice, not for the modulated one (as the SID bits)
00344         bool sync;              // Sync modulation bit
00345 };
00346 
00347 // Renderer class
00348 class DigitalRenderer : public SIDRenderer {
00349 public:
00350         DigitalRenderer(C64 *c64);
00351         virtual ~DigitalRenderer();
00352 
00353         virtual void Reset(void);
00354         virtual void EmulateLine(void);
00355         virtual void WriteRegister(uint16 adr, uint8 byte);
00356         virtual void NewPrefs(Prefs *prefs);
00357         virtual void Pause(void);
00358         virtual void Resume(void);
00359 
00360 private:
00361         void init_sound(void);
00362         void calc_filter(void);
00363 #if defined(__riscos__) || defined(__SYMBIAN32__)
00364         void calc_buffer(uint8 *buf, long count);
00365 #else
00366         void calc_buffer(int16 *buf, long count);
00367 #endif
00368 
00369         bool ready;                                             // Flag: Renderer has initialized and is ready
00370         uint8 volume;                                   // Master volume
00371         bool v3_mute;                                   // Voice 3 muted
00372 
00373         uint16 TriTable[0x1000*2];      // Tables for certain waveforms
00374         static const uint16 TriSawTable[0x100];
00375         static const uint16 TriRectTable[0x100];
00376         static const uint16 SawRectTable[0x100];
00377         static const uint16 TriSawRectTable[0x100];
00378         static const uint32 EGTable[16];        // Increment/decrement values for all A/D/R settings
00379         static const uint8 EGDRShift[256]; // For exponential approximation of D/R
00380         static const int16 SampleTab[16]; // Table for sampled voice
00381 
00382         DRVoice voice[3];                               // Data for 3 voices
00383 
00384         uint8 f_type;                                   // Filter type
00385         uint8 f_freq;                                   // SID filter frequency (upper 8 bits)
00386         uint8 f_res;                                    // Filter resonance (0..15)
00387 #ifdef USE_FIXPOINT_MATHS
00388         FixPoint f_ampl;
00389         FixPoint d1, d2, g1, g2;
00390         int32 xn1, xn2, yn1, yn2;               // can become very large
00391         FixPoint sidquot;
00392 #ifdef PRECOMPUTE_RESONANCE
00393         FixPoint resonanceLP[256];
00394         FixPoint resonanceHP[256];
00395 #endif
00396 #else
00397         float f_ampl;                                   // IIR filter input attenuation
00398         float d1, d2, g1, g2;                   // IIR filter coefficients
00399         float xn1, xn2, yn1, yn2;               // IIR filter previous input/output signal
00400 #ifdef PRECOMPUTE_RESONANCE
00401         float resonanceLP[256];                 // shortcut for calc_filter
00402         float resonanceHP[256];
00403 #endif
00404 #endif
00405 
00406         uint8 sample_buf[SAMPLE_BUF_SIZE]; // Buffer for sampled voice
00407         int sample_in_ptr;                              // Index in sample_buf for writing
00408 
00409 #ifdef __BEOS__
00410         static bool stream_func(void *arg, char *buf, size_t count, void *header);
00411         BDACStream *the_stream;                 // Pointer to stream
00412         BSubscriber *the_sub;                   // Pointer to subscriber
00413         bool in_stream;                                 // Flag: Subscriber has entered stream
00414 #endif
00415 
00416 #ifdef AMIGA
00417         static void sub_invoc(void);    // Sound sub-process
00418         void sub_func(void);
00419         struct Process *sound_process;
00420         int quit_sig, pause_sig,
00421                 resume_sig, ahi_sig;            // Sub-process signals
00422         struct Task *main_task;                 // Main task
00423         int main_sig;                                   // Main task signals
00424         static ULONG sound_func(void);  // AHI callback
00425         struct MsgPort *ahi_port;               // Port and IORequest for AHI
00426         struct AHIRequest *ahi_io;
00427         struct AHIAudioCtrl *ahi_ctrl;  // AHI control structure
00428         struct AHISampleInfo sample[2]; // SampleInfos for double buffering
00429         struct Hook sf_hook;                    // Hook for callback function
00430         int play_buf;                                   // Number of buffer currently playing
00431 #endif
00432 
00433 #ifdef __linux__
00434         int devfd, sndbufsize, buffer_rate;
00435         int16 *sound_buffer;
00436 #endif
00437 
00438 #ifdef SUN
00439         int fd;
00440         audio_info status;
00441         uint_t sent_samples,delta_samples;
00442         WORD *sound_calc_buf;
00443 #endif
00444 
00445 #ifdef __hpux
00446         int fd;
00447         audio_status status;
00448         int16 * sound_calc_buf;
00449         int linecnt;
00450 #endif
00451 
00452 #ifdef __mac__
00453         SndChannelPtr chan1;
00454         SndDoubleBufferHeader myDblHeader;
00455         SndDoubleBufferPtr sampleBuffer1, sampleBuffer2;
00456         SCStatus myStatus;
00457         short sndbufsize;
00458         OSErr err;
00459 
00460         static void doubleBackProc(SndChannelPtr chan, SndDoubleBufferPtr doubleBuffer);
00461 #endif
00462 
00463 #ifdef WIN32
00464 public:
00465         void VBlank(void);
00466 
00467 private:
00468         void StartPlayer(void);
00469         void StopPlayer(void);
00470 
00471         BOOL direct_sound;
00472         DigitalPlayer *ThePlayer;
00473         SWORD *sound_buffer;
00474         int to_output;
00475         int sb_pos;
00476         int divisor;
00477         int *lead;
00478         int lead_pos;
00479 #endif
00480 
00481 #ifdef __riscos__
00482         int linecnt, sndbufsize;
00483         uint8 *sound_buffer;
00484 #endif
00485 
00486 private: // methods
00487         uint8 sid_random();
00488 private: // members
00489         C64 *the_c64;                                   
00490 
00491 #ifndef GLOBAL_PREFS
00492         Prefs& ThePrefs;
00493 #endif
00494 
00495         uint32 seed;                    
00496 
00497 };
00498 
00502 uint8 DigitalRenderer::sid_random()
00503 {
00504         seed = seed * 1103515245 + 12345;
00505         return seed >> 16;
00506 }
00507 
00508 #ifndef EMUL_MOS8580
00509 // Sampled from a 6581R4
00510 const uint16 DigitalRenderer::TriSawTable[0x100] = {
00511         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00512         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00513         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00514         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00515         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00516         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00517         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00518         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0808,
00519         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00520         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00521         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00522         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00523         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00524         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00525         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00526         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1010, 0x3C3C,
00527         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00528         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00529         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00530         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00531         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00532         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00533         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00534         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0808,
00535         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00536         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00537         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00538         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00539         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00540         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00541         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00542         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1010, 0x3C3C
00543 };
00544 
00545 const uint16 DigitalRenderer::TriRectTable[0x100] = {
00546         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00547         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00548         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00549         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00550         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00551         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00552         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00553         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00554         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00555         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00556         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00557         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00558         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00559         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00560         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0xC0C0,
00561         0x0000, 0x8080, 0x8080, 0xE0E0, 0x8080, 0xE0E0, 0xF0F0, 0xFCFC,
00562         0xFFFF, 0xFCFC, 0xFAFA, 0xF0F0, 0xF6F6, 0xE0E0, 0xE0E0, 0x8080,
00563         0xEEEE, 0xE0E0, 0xE0E0, 0x8080, 0xC0C0, 0x0000, 0x0000, 0x0000,
00564         0xDEDE, 0xC0C0, 0xC0C0, 0x0000, 0x8080, 0x0000, 0x0000, 0x0000,
00565         0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00566         0xBEBE, 0x8080, 0x8080, 0x0000, 0x8080, 0x0000, 0x0000, 0x0000,
00567         0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00568         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00569         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00570         0x7E7E, 0x4040, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00571         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00572         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00573         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00574         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00575         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00576         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00577         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
00578 };
00579 
00580 const uint16 DigitalRenderer::SawRectTable[0x100] = {
00581         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00582         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00583         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00584         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00585         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00586         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00587         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00588         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00589         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00590         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00591         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00592         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00593         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00594         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00595         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00596         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7878,
00597         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00598         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00599         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00600         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00601         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00602         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00603         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00604         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00605         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00606         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00607         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00608         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00609         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00610         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00611         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00612         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7878
00613 };
00614 
00615 const uint16 DigitalRenderer::TriSawRectTable[0x100] = {
00616         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00617         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00618         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00619         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00620         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00621         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00622         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00623         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00624         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00625         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00626         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00627         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00628         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00629         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00630         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00631         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00632         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00633         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00634         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00635         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00636         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00637         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00638         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00639         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00640         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00641         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00642         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00643         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00644         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00645         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00646         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00647         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
00648 };
00649 #else
00650 // Sampled from an 8580R5
00651 const uint16 DigitalRenderer::TriSawTable[0x100] = {
00652         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00653         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00654         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00655         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00656         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00657         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00658         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00659         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0808,
00660         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00661         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00662         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00663         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00664         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00665         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00666         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00667         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1818, 0x3C3C,
00668         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00669         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00670         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00671         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00672         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00673         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00674         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00675         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1C1C,
00676         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00677         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00678         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00679         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00680         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00681         0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0x0000, 0x8080, 0x8080,
00682         0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xE0E0,
00683         0xF0F0, 0xF0F0, 0xF0F0, 0xF0F0, 0xF8F8, 0xF8F8, 0xFCFC, 0xFEFE
00684 };
00685 
00686 const uint16 DigitalRenderer::TriRectTable[0x100] = {
00687         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00688         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00689         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00690         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00691         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00692         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00693         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00694         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00695         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00696         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00697         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00698         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00699         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00700         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00701         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00702         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00703         0xFFFF, 0xFCFC, 0xF8F8, 0xF0F0, 0xF4F4, 0xF0F0, 0xF0F0, 0xE0E0,
00704         0xECEC, 0xE0E0, 0xE0E0, 0xC0C0, 0xE0E0, 0xC0C0, 0xC0C0, 0xC0C0,
00705         0xDCDC, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0x8080, 0x8080,
00706         0xC0C0, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x0000, 0x0000,
00707         0xBEBE, 0xA0A0, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x0000,
00708         0x8080, 0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00709         0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00710         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00711         0x7E7E, 0x7070, 0x6060, 0x0000, 0x4040, 0x0000, 0x0000, 0x0000,
00712         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00713         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00714         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00715         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00716         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00717         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00718         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
00719 };
00720 
00721 const uint16 DigitalRenderer::SawRectTable[0x100] = {
00722         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00723         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00724         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00725         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00726         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00727         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00728         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00729         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00730         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00731         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00732         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00733         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00734         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00735         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00736         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00737         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00738         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00739         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00740         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00741         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00742         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00743         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00744         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0x8080,
00745         0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xB0B0, 0xBEBE,
00746         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00747         0x0000, 0x0000, 0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0,
00748         0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0,
00749         0x8080, 0x8080, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xDCDC,
00750         0x8080, 0x8080, 0x8080, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0,
00751         0xC0C0, 0xC0C0, 0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xE0E0, 0xECEC,
00752         0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xE0E0, 0xF0F0, 0xF0F0, 0xF4F4,
00753         0xF0F0, 0xF0F0, 0xF8F8, 0xF8F8, 0xF8F8, 0xFCFC, 0xFEFE, 0xFFFF
00754 };
00755 
00756 const uint16 DigitalRenderer::TriSawRectTable[0x100] = {
00757         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00758         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00759         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00760         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00761         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00762         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00763         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00764         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00765         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00766         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00767         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00768         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00769         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00770         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00771         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00772         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00773         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00774         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00775         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00776         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00777         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00778         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00779         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00780         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00781         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00782         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00783         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00784         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00785         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00786         0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0x8080,
00787         0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0, 0xC0C0,
00788         0xC0C0, 0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xF0F0, 0xF8F8, 0xFCFC
00789 };
00790 #endif
00791 
00792 const uint32 DigitalRenderer::EGTable[16] = {
00793         (SID_CYCLES << 16) / 9, (SID_CYCLES << 16) / 32,
00794         (SID_CYCLES << 16) / 63, (SID_CYCLES << 16) / 95,
00795         (SID_CYCLES << 16) / 149, (SID_CYCLES << 16) / 220,
00796         (SID_CYCLES << 16) / 267, (SID_CYCLES << 16) / 313,
00797         (SID_CYCLES << 16) / 392, (SID_CYCLES << 16) / 977,
00798         (SID_CYCLES << 16) / 1954, (SID_CYCLES << 16) / 3126,
00799         (SID_CYCLES << 16) / 3906, (SID_CYCLES << 16) / 11720,
00800         (SID_CYCLES << 16) / 19531, (SID_CYCLES << 16) / 31251
00801 };
00802 
00803 const uint8 DigitalRenderer::EGDRShift[256] = {
00804         5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,
00805         3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,
00806         2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
00807         2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
00808         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00809         1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00810         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00811         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00812         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00813         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00814         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00815         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00816         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00817         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00818         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00819         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00820 };
00821 
00822 const int16 DigitalRenderer::SampleTab[16] = {
00823         0x8000, 0x9111, 0xa222, 0xb333, 0xc444, 0xd555, 0xe666, 0xf777,
00824         0x0888, 0x1999, 0x2aaa, 0x3bbb, 0x4ccc, 0x5ddd, 0x6eee, 0x7fff,
00825 };
00826 
00827 
00828 /*
00829  *  Constructor
00830  */
00831 
00832 DigitalRenderer::DigitalRenderer(C64 *c64)
00833         :the_c64(c64)
00834         ,ThePrefs(c64->ThePrefs)
00835         ,seed(1)
00836 {
00837         __CHECK_NULL(c64);
00838 
00839         // Link voices together
00840         voice[0].mod_by = &voice[2];
00841         voice[1].mod_by = &voice[0];
00842         voice[2].mod_by = &voice[1];
00843         voice[0].mod_to = &voice[1];
00844         voice[1].mod_to = &voice[2];
00845         voice[2].mod_to = &voice[0];
00846 
00847         // Calculate triangle table
00848         for (int i=0; i<0x1000; i++) {
00849                 TriTable[i] = (i << 4) | (i >> 8);
00850                 TriTable[0x1fff-i] = (i << 4) | (i >> 8);
00851         }
00852 
00853 #ifdef PRECOMPUTE_RESONANCE
00854 #ifdef USE_FIXPOINT_MATHS
00855         // slow floating point doesn't matter much on startup!
00856         for (int j=0; j<256; j++) {
00857           resonanceLP[j] = FixNo(CALC_RESONANCE_LP(j));
00858           resonanceHP[j] = FixNo(CALC_RESONANCE_HP(j));
00859         }
00860         // Pre-compute the quotient. No problem since int-part is small enough
00861         sidquot = (int32)((((double)SID_FREQ)*65536) / SAMPLE_FREQ);
00862         // compute lookup table for sin and cos
00863         InitFixSinTab();
00864 #else
00865         for (int j=0; j<256; j++) {
00866           resonanceLP[j] = CALC_RESONANCE_LP(j);
00867           resonanceHP[j] = CALC_RESONANCE_HP(j);
00868         }
00869 #endif
00870 #endif
00871 
00872         Reset();
00873 
00874         // System specific initialization
00875         init_sound();
00876 }
00877 
00878 
00879 /*
00880  *  Reset emulation
00881  */
00882 
00883 void DigitalRenderer::Reset(void)
00884 {
00885         volume = 0;
00886         v3_mute = false;
00887 
00888         for (int v=0; v<3; v++) {
00889                 voice[v].wave = WAVE_NONE;
00890                 voice[v].eg_state = EG_IDLE;
00891                 voice[v].count = voice[v].add = 0;
00892                 voice[v].freq = voice[v].pw = 0;
00893                 voice[v].eg_level = voice[v].s_level = 0;
00894                 voice[v].a_add = voice[v].d_sub = voice[v].r_sub = EGTable[0];
00895                 voice[v].gate = voice[v].ring = voice[v].test = false;
00896                 voice[v].filter = voice[v].sync = false;
00897         }
00898 
00899         f_type = FILT_NONE;
00900         f_freq = f_res = 0;
00901 #ifdef USE_FIXPOINT_MATHS
00902         f_ampl = FixNo(1);
00903         d1 = d2 = g1 = g2 = 0;
00904         xn1 = xn2 = yn1 = yn2 = 0;
00905 #else
00906         f_ampl = 1.0;
00907         d1 = d2 = g1 = g2 = 0.0;
00908         xn1 = xn2 = yn1 = yn2 = 0.0;
00909 #endif
00910 
00911         sample_in_ptr = 0;
00912         memset(sample_buf, 0, SAMPLE_BUF_SIZE);
00913 
00914         ELOG1(_L8("Digital renderer reset\n"));
00915 
00916 }
00917 
00918 
00919 /*
00920  *  Write to register
00921  */
00922 
00923 void DigitalRenderer::WriteRegister(uint16 adr, uint8 byte)
00924 {
00925         if (!ready)
00926                 return;
00927 
00928         int v = adr/7;  // Voice number
00929 
00930         switch (adr) {
00931                 case 0:
00932                 case 7:
00933                 case 14:
00934                         voice[v].freq = (voice[v].freq & 0xff00) | byte;
00935 #ifdef USE_FIXPOINT_MATHS
00936                         voice[v].add = sidquot.imul((int)voice[v].freq);
00937 #else
00938                         voice[v].add = (uint32)(voice[v].freq * SID_FREQ / SAMPLE_FREQ);
00939 #endif
00940                         break;
00941 
00942                 case 1:
00943                 case 8:
00944                 case 15:
00945                         voice[v].freq = (voice[v].freq & 0xff) | (byte << 8);
00946 #ifdef USE_FIXPOINT_MATHS
00947                         voice[v].add = sidquot.imul((int)voice[v].freq);
00948 #else
00949                         voice[v].add = (uint32)(voice[v].freq * SID_FREQ / SAMPLE_FREQ);
00950 #endif
00951                         break;
00952 
00953                 case 2:
00954                 case 9:
00955                 case 16:
00956                         voice[v].pw = (voice[v].pw & 0x0f00) | byte;
00957                         break;
00958 
00959                 case 3:
00960                 case 10:
00961                 case 17:
00962                         voice[v].pw = (voice[v].pw & 0xff) | ((byte & 0xf) << 8);
00963                         break;
00964 
00965                 case 4:
00966                 case 11:
00967                 case 18:
00968                         voice[v].wave = (byte >> 4) & 0xf;
00969                         if ((byte & 1) != voice[v].gate)
00970                                 if (byte & 1)   // Gate turned on
00971                                         voice[v].eg_state = EG_ATTACK;
00972                                 else                    // Gate turned off
00973                                         if (voice[v].eg_state != EG_IDLE)
00974                                                 voice[v].eg_state = EG_RELEASE;
00975                         voice[v].gate = byte & 1;
00976                         voice[v].mod_by->sync = byte & 2;
00977                         voice[v].ring = byte & 4;
00978                         if ((voice[v].test = byte & 8))
00979                                 voice[v].count = 0;
00980                         break;
00981 
00982                 case 5:
00983                 case 12:
00984                 case 19:
00985                         voice[v].a_add = EGTable[byte >> 4];
00986                         voice[v].d_sub = EGTable[byte & 0xf];
00987                         break;
00988 
00989                 case 6:
00990                 case 13:
00991                 case 20:
00992                         voice[v].s_level = (byte >> 4) * 0x111111;
00993                         voice[v].r_sub = EGTable[byte & 0xf];
00994                         break;
00995 
00996                 case 22:
00997                         if (byte != f_freq) {
00998                                 f_freq = byte;
00999                                 if (ThePrefs.SIDFilters)
01000                                         calc_filter();
01001                         }
01002                         break;
01003 
01004                 case 23:
01005                         voice[0].filter = byte & 1;
01006                         voice[1].filter = byte & 2;
01007                         voice[2].filter = byte & 4;
01008                         if ((byte >> 4) != f_res) {
01009                                 f_res = byte >> 4;
01010                                 if (ThePrefs.SIDFilters)
01011                                         calc_filter();
01012                         }
01013                         break;
01014 
01015                 case 24:
01016                         volume = byte & 0xf;
01017                         v3_mute = byte & 0x80;
01018                         if (((byte >> 4) & 7) != f_type) {
01019                                 f_type = (byte >> 4) & 7;
01020 #ifdef USE_FIXPOINT_MATHS
01021                                 xn1 = xn2 = yn1 = yn2 = 0;
01022 #else
01023                                 xn1 = xn2 = yn1 = yn2 = 0.0;
01024 #endif
01025                                 if (ThePrefs.SIDFilters)
01026                                         calc_filter();
01027                         }
01028                         break;
01029         }
01030 }
01031 
01032 
01033 /*
01034  *  Preferences may have changed
01035  */
01036 
01037 void DigitalRenderer::NewPrefs(Prefs *prefs)
01038 {
01039         calc_filter();
01040 }
01041 
01042 
01043 /*
01044  *  Calculate IIR filter coefficients
01045  */
01046 
01047 void DigitalRenderer::calc_filter(void)
01048 {
01049 #ifdef USE_FIXPOINT_MATHS
01050         FixPoint fr, arg;
01051 
01052         if (f_type == FILT_ALL)
01053         {
01054                 d1 = 0; d2 = 0; g1 = 0; g2 = 0; f_ampl = FixNo(1); return;
01055         }
01056         else if (f_type == FILT_NONE)
01057         {
01058                 d1 = 0; d2 = 0; g1 = 0; g2 = 0; f_ampl = 0; return;
01059         }
01060 #else
01061         float fr, arg;
01062 
01063         // Check for some trivial cases
01064         if (f_type == FILT_ALL) {
01065                 d1 = 0.0; d2 = 0.0;
01066                 g1 = 0.0; g2 = 0.0;
01067                 f_ampl = 1.0;
01068                 return;
01069         } else if (f_type == FILT_NONE) {
01070                 d1 = 0.0; d2 = 0.0;
01071                 g1 = 0.0; g2 = 0.0;
01072                 f_ampl = 0.0;
01073                 return;
01074         }
01075 #endif
01076 
01077         // Calculate resonance frequency
01078         if (f_type == FILT_LP || f_type == FILT_LPBP)
01079 #ifdef PRECOMPUTE_RESONANCE
01080                 fr = resonanceLP[f_freq];
01081 #else
01082                 fr = CALC_RESONANCE_LP(f_freq);
01083 #endif
01084         else
01085 #ifdef PRECOMPUTE_RESONANCE
01086                 fr = resonanceHP[f_freq];
01087 #else
01088                 fr = CALC_RESONANCE_HP(f_freq);
01089 #endif
01090 
01091 #ifdef USE_FIXPOINT_MATHS
01092         // explanations see below.
01093         arg = fr / (SAMPLE_FREQ >> 1);
01094         if (arg > FixNo(0.99)) {arg = FixNo(0.99);}
01095         if (arg < FixNo(0.01)) {arg = FixNo(0.01);}
01096 
01097         g2 = FixNo(0.55) + FixNo(1.2) * arg * (arg - 1) + FixNo(0.0133333333) * f_res;
01098         g1 = FixNo(-2) * g2.sqrt() * fixcos(arg);
01099 
01100         if (f_type == FILT_LPBP || f_type == FILT_HPBP) {g2 += FixNo(0.1);}
01101 
01102         if (g1.abs() >= g2 + 1)
01103         {
01104           if (g1 > 0) {g1 = g2 + FixNo(0.99);}
01105           else {g1 = -(g2 + FixNo(0.99));}
01106         }
01107 
01108         switch (f_type)
01109         {
01110           case FILT_LPBP:
01111           case FILT_LP:
01112                 d1 = FixNo(2); d2 = FixNo(1); f_ampl = FixNo(0.25) * (1 + g1 + g2); break;
01113           case FILT_HPBP:
01114           case FILT_HP:
01115                 d1 = FixNo(-2); d2 = FixNo(1); f_ampl = FixNo(0.25) * (1 - g1 + g2); break;
01116           case FILT_BP:
01117                 d1 = 0; d2 = FixNo(-1);
01118                 f_ampl = FixNo(0.25) * (1 + g1 + g2) * (1 + fixcos(arg)) / fixsin(arg);
01119                 break;
01120           case FILT_NOTCH:
01121                 d1 = FixNo(-2) * fixcos(arg); d2 = FixNo(1);
01122                 f_ampl = FixNo(0.25) * (1 + g1 + g2) * (1 + fixcos(arg)) / fixsin(arg);
01123                 break;
01124           default: break;
01125         }
01126 
01127 #else // USE_FIXPOINT_MATHS
01128 
01129         // Limit to <1/2 sample frequency, avoid div by 0 in case FILT_BP below
01130         arg = fr / (float)(SAMPLE_FREQ >> 1);
01131         if (arg > 0.99)
01132                 arg = 0.99;
01133         if (arg < 0.01)
01134                 arg = 0.01;
01135 
01136         // Calculate poles (resonance frequency and resonance)
01137         g2 = (float)(0.55 + 1.2 * arg * arg - 1.2 * arg + (float)f_res * 0.0133333333);
01138         g1 = (float)(-2.0 * sqrt(g2) * cos(M_PI * arg));
01139 
01140         // Increase resonance if LP/HP combined with BP
01141         if (f_type == FILT_LPBP || f_type == FILT_HPBP)
01142                 g2 += 0.1;
01143 
01144         // Stabilize filter
01145         if (fabs(g1) >= g2 + 1.0)
01146                 if (g1 > 0.0)
01147                         g1 = g2 + 0.99;
01148                 else
01149                         g1 = -(g2 + 0.99);
01150 
01151         // Calculate roots (filter characteristic) and input attenuation
01152         switch (f_type) {
01153 
01154                 case FILT_LPBP:
01155                 case FILT_LP:
01156                         d1 = 2.0; d2 = 1.0;
01157                         f_ampl = 0.25 * (1.0 + g1 + g2);
01158                         break;
01159 
01160                 case FILT_HPBP:
01161                 case FILT_HP:
01162                         d1 = -2.0; d2 = 1.0;
01163                         f_ampl = 0.25 * (1.0 - g1 + g2);
01164                         break;
01165 
01166                 case FILT_BP:
01167                         d1 = 0.0; d2 = -1.0;
01168                         f_ampl = (float)(0.25 * (1.0 + g1 + g2) * (1 + cos(M_PI * arg)) / sin(M_PI * arg));
01169                         break;
01170 
01171                 case FILT_NOTCH:
01172                         d1 = (float)(-2.0 * cos(M_PI * arg)); d2 = 1.0;
01173                         f_ampl = (float)(0.25 * (1.0 + g1 + g2) * (1 + cos(M_PI * arg)) / (sin(M_PI * arg)));
01174                         break;
01175 
01176                 default:
01177                         break;
01178         }
01179 #endif // USE_FIXPOINT_MATHS
01180 }
01181 
01182 
01186 #if defined(__riscos__) || defined(__SYMBIAN32__)
01187 void DigitalRenderer::calc_buffer(uint8 *buf, long count)
01188 #else
01189 void DigitalRenderer::calc_buffer(int16 *buf, long count)
01190 #endif
01191 {
01192         // Get filter coefficients, so the emulator won't change
01193         // them in the middle of our calculations
01194 #ifdef USE_FIXPOINT_MATHS
01195         FixPoint cf_ampl = f_ampl;
01196         FixPoint cd1 = d1, cd2 = d2, cg1 = g1, cg2 = g2;
01197 #else
01198         float cf_ampl = f_ampl;
01199         float cd1 = d1, cd2 = d2, cg1 = g1, cg2 = g2;
01200 #endif
01201 
01202 #ifdef __riscos__
01203         uint8 *LinToLog, *LogScale;
01204 #endif
01205 
01206         // Index in sample_buf for reading, 16.16 fixed
01207         uint32 sample_count = (sample_in_ptr + SAMPLE_BUF_SIZE/2) << 16;
01208 
01209 #ifdef __riscos__       // on RISC OS we have 8 bit logarithmic sound
01210         DigitalRenderer_GetTables(&LinToLog, &LogScale);        // get translation tables
01211 #else
01212 #ifdef __BEOS__
01213         count >>= 2;    // 16 bit stereo output, count is in bytes
01214 #else
01215         count >>= 1;    // 16 bit mono output, count is in bytes
01216 #endif
01217 #endif
01218         while (count--) {
01219                 int32 sum_output;
01220                 int32 sum_output_filter = 0;
01221 
01222                 // Get current master volume from sample buffer,
01223                 // calculate sampled voice
01224                 uint8 master_volume = sample_buf[(sample_count >> 16) % SAMPLE_BUF_SIZE];
01225                 sample_count += ((0x138 * 50) << 16) / SAMPLE_FREQ;
01226                 sum_output = SampleTab[master_volume] << 8;
01227 
01228                 // Loop for all three voices
01229                 for (int j=0; j<3; j++) {
01230                         DRVoice *v = &voice[j];
01231 
01232                         // Envelope generators
01233                         uint16 envelope;
01234 
01235                         switch (v->eg_state) {
01236                                 case EG_ATTACK:
01237                                         v->eg_level += v->a_add;
01238                                         if (v->eg_level > 0xffffff) {
01239                                                 v->eg_level = 0xffffff;
01240                                                 v->eg_state = EG_DECAY;
01241                                         }
01242                                         break;
01243                                 case EG_DECAY:
01244                                         if (v->eg_level <= v->s_level || v->eg_level > 0xffffff)
01245                                                 v->eg_level = v->s_level;
01246                                         else {
01247                                                 v->eg_level -= v->d_sub >> EGDRShift[v->eg_level >> 16];
01248                                                 if (v->eg_level <= v->s_level || v->eg_level > 0xffffff)
01249                                                         v->eg_level = v->s_level;
01250                                         }
01251                                         break;
01252                                 case EG_RELEASE:
01253                                         v->eg_level -= v->r_sub >> EGDRShift[v->eg_level >> 16];
01254                                         if (v->eg_level > 0xffffff) {
01255                                                 v->eg_level = 0;
01256                                                 v->eg_state = EG_IDLE;
01257                                         }
01258                                         break;
01259                                 case EG_IDLE:
01260                                         v->eg_level = 0;
01261                                         break;
01262                         }
01263                         envelope = (v->eg_level * master_volume) >> 20;
01264 
01265                         // Waveform generator
01266                         uint16 output;
01267 
01268                         if (!v->test)
01269                                 v->count += v->add;
01270 
01271                         if (v->sync && (v->count > 0x1000000))
01272                                 v->mod_to->count = 0;
01273 
01274                         v->count &= 0xffffff;
01275 
01276                         switch (v->wave) {
01277                                 case WAVE_TRI:
01278                                         if (v->ring)
01279                                                 output = TriTable[(v->count ^ (v->mod_by->count & 0x800000)) >> 11];
01280                                         else
01281                                                 output = TriTable[v->count >> 11];
01282                                         break;
01283                                 case WAVE_SAW:
01284                                         output = v->count >> 8;
01285                                         break;
01286                                 case WAVE_RECT:
01287                                         if (v->count > (uint32)(v->pw << 12))
01288                                                 output = 0xffff;
01289                                         else
01290                                                 output = 0;
01291                                         break;
01292                                 case WAVE_TRISAW:
01293                                         output = TriSawTable[v->count >> 16];
01294                                         break;
01295                                 case WAVE_TRIRECT:
01296                                         if (v->count > (uint32)(v->pw << 12))
01297                                                 output = TriRectTable[v->count >> 16];
01298                                         else
01299                                                 output = 0;
01300                                         break;
01301                                 case WAVE_SAWRECT:
01302                                         if (v->count > (uint32)(v->pw << 12))
01303                                                 output = SawRectTable[v->count >> 16];
01304                                         else
01305                                                 output = 0;
01306                                         break;
01307                                 case WAVE_TRISAWRECT:
01308                                         if (v->count > (uint32)(v->pw << 12))
01309                                                 output = TriSawRectTable[v->count >> 16];
01310                                         else
01311                                                 output = 0;
01312                                         break;
01313                                 case WAVE_NOISE:
01314                                         if (v->count > 0x100000) {
01315                                                 output = v->noise = sid_random() << 8;
01316                                                 v->count &= 0xfffff;
01317                                         } else
01318                                                 output = v->noise;
01319                                         break;
01320                                 default:
01321                                         output = 0x8000;
01322                                         break;
01323                         }
01324                         if (v->filter)
01325                                 sum_output_filter += (int16)(output ^ 0x8000) * envelope;
01326                         else
01327                                 sum_output += (int16)(output ^ 0x8000) * envelope;
01328                 }
01329 
01330                 // Filter
01331                 if (ThePrefs.SIDFilters) {
01332 #ifdef USE_FIXPOINT_MATHS
01333                         int32 xn = cf_ampl.imul(sum_output_filter);
01334                         int32 yn = xn+cd1.imul(xn1)+cd2.imul(xn2)-cg1.imul(yn1)-cg2.imul(yn2);
01335                         yn2 = yn1; yn1 = yn; xn2 = xn1; xn1 = xn;
01336                         sum_output_filter = yn;
01337 #else
01338                         float xn = (float)sum_output_filter * cf_ampl;
01339                         float yn = xn + cd1 * xn1 + cd2 * xn2 - cg1 * yn1 - cg2 * yn2;
01340                         yn2 = yn1; yn1 = yn; xn2 = xn1; xn1 = xn;
01341                         sum_output_filter = (int32)yn;
01342 #endif
01343                 }
01344 
01345                 // Write to buffer
01346 #ifdef __BEOS__
01347                 int16 audio_data = (sum_output + sum_output_filter) >> 10;
01348                 int val = *buf + audio_data;
01349                 if (val > 32767)
01350                         val = 32767;
01351                 if (val < -32768)
01352                         val = -32768;
01353                 *buf++ = val;
01354                 val = *buf + audio_data;
01355                 if (val > 32767)
01356                         val = 32767;
01357                 if (val < -32768)
01358                         val = -32768;
01359                 *buf++ = val;
01360 #elif defined(__riscos__)       // lookup in 8k (13bit) translation table
01361                 *buf++ = LinToLog[((sum_output + sum_output_filter) >> 13) & 0x1fff];
01362 #else
01363                 *buf++ = (sum_output + sum_output_filter) >> 10;
01364 #endif
01365         }
01366 }
01367 
01368 
01369 // Manufacturer independent sound is still just a dream...
01370 #if defined(__SYMBIAN32__) // must be before __linux__ in case of using the GnuPoc SDK
01371 #include "sid_epoc32.i"
01372 
01373 #elif defined(__BEOS__)
01374 #include "SID_Be.i"
01375 
01376 #elif defined(AMIGA)
01377 #include "SID_Amiga.i"
01378 
01379 #elif defined(__linux__)
01380 #include "SID_linux.i"
01381 
01382 #elif defined(SUN)
01383 #include "SID_sun.i"
01384 
01385 #elif defined(__hpux)
01386 #include "SID_hp.i"
01387 
01388 #elif defined(__mac__)
01389 #include "SID_mac.i"
01390 
01391 #elif defined(WIN32)
01392 #include "SID_WIN32.i"
01393 
01394 #elif defined(__riscos__)
01395 #include "SID_Acorn.i"
01396 
01397 #else   // No sound
01398 void DigitalRenderer::init_sound(void) {ready = false;}
01399 DigitalRenderer::~DigitalRenderer() {}
01400 void DigitalRenderer::EmulateLine(void) {}
01401 void DigitalRenderer::Pause(void) {}
01402 void DigitalRenderer::Resume(void) {}
01403 #endif
01404 
01405 
01406 /*
01407  *  Open/close the renderer, according to old and new prefs
01408  */
01409 
01410 void MOS6581::open_close_renderer(int old_type, int new_type)
01411 {
01412         if (old_type == new_type)
01413                 return;
01414 
01415         // Delete the old renderer
01416         delete the_renderer;
01417 
01418         // Create new renderer
01419         if (new_type == SIDTYPE_DIGITAL)
01420                 the_renderer = new DigitalRenderer(the_c64);
01421 
01422 #ifdef AMIGA
01423         else if (new_type == SIDTYPE_SIDCARD)
01424                 the_renderer = new SIDCardRenderer();
01425 #endif
01426         else
01427                 the_renderer = NULL;
01428 
01429         // Stuff the current register values into the new renderer
01430         if (the_renderer != NULL)
01431                 for (int i=0; i<25; i++)
01432                         the_renderer->WriteRegister(i, regs[i]);
01433 }

Generated on Tue Feb 8 04:08:11 2005 for E32frodo by doxygen 1.3.3