00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00075 #include "VIC.h"
00076 #ifndef __ER6__
00077 #include <d32snd.h>
00078 #else
00079 #include <mda/common/audio.h>
00080 #include <mdaaudiooutputstream.h>
00081 #endif // __ER6__
00082
00083 #endif // __SYMBIAN32__
00084
00085
00086 #ifdef USE_FIXPOINT_MATHS
00087 #include "FixPoint.i"
00088 #endif
00089
00090
00091
00092
00093
00094
00095 #define CALC_RESONANCE_LP(f) (227.755\
00096 - 1.7635 * f\
00097 - 0.0176385 * f * f\
00098 + 0.00333484 * f * f * f\
00099 - 9.05683E-6 * f * f * f * f)
00100
00101 #define CALC_RESONANCE_HP(f) (366.374\
00102 - 14.0052 * f\
00103 + 0.603212 * f * f\
00104 - 0.000880196 * f * f * f)
00105
00106
00107
00108
00112 MOS6581::MOS6581(C64 *c64) : the_c64(c64), ThePrefs(c64->ThePrefs)
00113 {
00114 __CHECK_NULL(c64);
00115
00116 the_renderer = NULL;
00117 for (int i=0; i<32; i++)
00118 regs[i] = 0;
00119
00120
00121 open_close_renderer(SIDTYPE_NONE, ThePrefs.SIDType);
00122
00123 CTOR(MOS6581);
00124 }
00125
00126
00130 MOS6581::~MOS6581()
00131 {
00132
00133 open_close_renderer(ThePrefs.SIDType, SIDTYPE_NONE);
00134
00135 DTOR(MOS6581);
00136 }
00137
00138
00142 void MOS6581::Reset(void)
00143 {
00144 for (int i=0; i<32; i++)
00145 regs[i] = 0;
00146 last_sid_byte = 0;
00147
00148
00149 if (the_renderer != NULL)
00150 the_renderer->Reset();
00151
00152 ELOG1(_L8("SID reset\n"));
00153 }
00154
00155
00156
00157
00158
00159
00160 void MOS6581::NewPrefs(Prefs *prefs)
00161 {
00162 open_close_renderer(ThePrefs.SIDType, prefs->SIDType);
00163 if (the_renderer != NULL)
00164 the_renderer->NewPrefs(prefs);
00165 }
00166
00167
00168
00169
00170
00171
00172 void MOS6581::PauseSound(void)
00173 {
00174 if (the_renderer != NULL)
00175 the_renderer->Pause();
00176 }
00177
00178
00179
00180
00181
00182
00183 void MOS6581::ResumeSound(void)
00184 {
00185 if (the_renderer != NULL)
00186 the_renderer->Resume();
00187 }
00188
00189
00190
00191
00192
00193
00194 void MOS6581::GetState(MOS6581State *ss)
00195 {
00196 ss->freq_lo_1 = regs[0];
00197 ss->freq_hi_1 = regs[1];
00198 ss->pw_lo_1 = regs[2];
00199 ss->pw_hi_1 = regs[3];
00200 ss->ctrl_1 = regs[4];
00201 ss->AD_1 = regs[5];
00202 ss->SR_1 = regs[6];
00203
00204 ss->freq_lo_2 = regs[7];
00205 ss->freq_hi_2 = regs[8];
00206 ss->pw_lo_2 = regs[9];
00207 ss->pw_hi_2 = regs[10];
00208 ss->ctrl_2 = regs[11];
00209 ss->AD_2 = regs[12];
00210 ss->SR_2 = regs[13];
00211
00212 ss->freq_lo_3 = regs[14];
00213 ss->freq_hi_3 = regs[15];
00214 ss->pw_lo_3 = regs[16];
00215 ss->pw_hi_3 = regs[17];
00216 ss->ctrl_3 = regs[18];
00217 ss->AD_3 = regs[19];
00218 ss->SR_3 = regs[20];
00219
00220 ss->fc_lo = regs[21];
00221 ss->fc_hi = regs[22];
00222 ss->res_filt = regs[23];
00223 ss->mode_vol = regs[24];
00224
00225 ss->pot_x = 0xff;
00226 ss->pot_y = 0xff;
00227 ss->osc_3 = 0;
00228 ss->env_3 = 0;
00229 }
00230
00231
00232
00233
00234
00235
00236 void MOS6581::SetState(MOS6581State *ss)
00237 {
00238 regs[0] = ss->freq_lo_1;
00239 regs[1] = ss->freq_hi_1;
00240 regs[2] = ss->pw_lo_1;
00241 regs[3] = ss->pw_hi_1;
00242 regs[4] = ss->ctrl_1;
00243 regs[5] = ss->AD_1;
00244 regs[6] = ss->SR_1;
00245
00246 regs[7] = ss->freq_lo_2;
00247 regs[8] = ss->freq_hi_2;
00248 regs[9] = ss->pw_lo_2;
00249 regs[10] = ss->pw_hi_2;
00250 regs[11] = ss->ctrl_2;
00251 regs[12] = ss->AD_2;
00252 regs[13] = ss->SR_2;
00253
00254 regs[14] = ss->freq_lo_3;
00255 regs[15] = ss->freq_hi_3;
00256 regs[16] = ss->pw_lo_3;
00257 regs[17] = ss->pw_hi_3;
00258 regs[18] = ss->ctrl_3;
00259 regs[19] = ss->AD_3;
00260 regs[20] = ss->SR_3;
00261
00262 regs[21] = ss->fc_lo;
00263 regs[22] = ss->fc_hi;
00264 regs[23] = ss->res_filt;
00265 regs[24] = ss->mode_vol;
00266
00267
00268 if (the_renderer != NULL)
00269 for (int i=0; i<25; i++)
00270 the_renderer->WriteRegister(i, regs[i]);
00271 }
00272
00273
00278 #if defined(__SYMBIAN32__)
00279 const uint32 SAMPLE_FREQ = 8000;
00280 #elif defined(AMIGA) || defined(__riscos__)
00281 const uint32 SAMPLE_FREQ = 22050;
00282 #else
00283 const uint32 SAMPLE_FREQ = 44100;
00284 #endif
00285 const uint32 SID_FREQ = 985248;
00286 const uint32 CALC_FREQ = 50;
00287 const uint32 SID_CYCLES = SID_FREQ/SAMPLE_FREQ;
00288 const int SAMPLE_BUF_SIZE = 0x138*2;
00289
00290
00291 enum {
00292 WAVE_NONE,
00293 WAVE_TRI,
00294 WAVE_SAW,
00295 WAVE_TRISAW,
00296 WAVE_RECT,
00297 WAVE_TRIRECT,
00298 WAVE_SAWRECT,
00299 WAVE_TRISAWRECT,
00300 WAVE_NOISE
00301 };
00302
00303
00304 enum {
00305 EG_IDLE,
00306 EG_ATTACK,
00307 EG_DECAY,
00308 EG_RELEASE
00309 };
00310
00311
00312 enum {
00313 FILT_NONE,
00314 FILT_LP,
00315 FILT_BP,
00316 FILT_LPBP,
00317 FILT_HP,
00318 FILT_NOTCH,
00319 FILT_HPBP,
00320 FILT_ALL
00321 };
00322
00323
00324 struct DRVoice {
00325 int wave;
00326 int eg_state;
00327 DRVoice *mod_by;
00328 DRVoice *mod_to;
00329
00330 uint32 count;
00331 uint32 add;
00332
00333 uint16 freq;
00334 uint16 pw;
00335
00336 uint32 a_add;
00337 uint32 d_sub;
00338 uint32 s_level;
00339 uint32 r_sub;
00340 uint32 eg_level;
00341
00342 uint32 noise;
00343
00344 bool gate;
00345 bool ring;
00346 bool test;
00347 bool filter;
00348
00349
00350
00351 bool sync;
00352 };
00353
00354
00358 class DigitalRenderer : public SIDRenderer
00359 #ifdef __ER6__
00360 ,public SidDebugData
00361 ,public MMdaAudioOutputStreamCallback
00362 #endif
00363 {
00364 public:
00365 DigitalRenderer(C64 *c64);
00366 virtual ~DigitalRenderer();
00367
00368 virtual void Reset(void);
00369 virtual void EmulateLine(void);
00370 virtual void WriteRegister(uint16 adr, uint8 byte);
00371 virtual void NewPrefs(Prefs *prefs);
00372 virtual void Pause(void);
00373 virtual void Resume(void);
00374
00375 private:
00376 void init_sound(void);
00377 void calc_filter(void);
00378 #if defined(__riscos__)
00379 void calc_buffer(uint8 *buf, long count);
00380 #else
00381 void calc_buffer(int16 *buf, long count);
00382 #endif
00383
00384 bool ready;
00385 uint8 volume;
00386 bool v3_mute;
00387
00388 uint16 TriTable[0x1000*2];
00389 static const uint16 TriSawTable[0x100];
00390 static const uint16 TriRectTable[0x100];
00391 static const uint16 SawRectTable[0x100];
00392 static const uint16 TriSawRectTable[0x100];
00393 static const uint32 EGTable[16];
00394 static const uint8 EGDRShift[256];
00395 static const int16 SampleTab[16];
00396
00397 DRVoice voice[3];
00398
00399 uint8 f_type;
00400 uint8 f_freq;
00401 uint8 f_res;
00402 #ifdef USE_FIXPOINT_MATHS
00403 FixPoint f_ampl;
00404 FixPoint d1, d2, g1, g2;
00405 int32 xn1, xn2, yn1, yn2;
00406 FixPoint sidquot;
00407 #ifdef PRECOMPUTE_RESONANCE
00408 FixPoint resonanceLP[256];
00409 FixPoint resonanceHP[256];
00410 #endif
00411 #else
00412 float f_ampl;
00413 float d1, d2, g1, g2;
00414 float xn1, xn2, yn1, yn2;
00415 #ifdef PRECOMPUTE_RESONANCE
00416 float resonanceLP[256];
00417 float resonanceHP[256];
00418 #endif
00419 #endif
00420
00421 uint8 sample_buf[SAMPLE_BUF_SIZE];
00422 int sample_in_ptr;
00423
00424 #ifdef __BEOS__
00425 static bool stream_func(void *arg, char *buf, size_t count, void *header);
00426 BDACStream *the_stream;
00427 BSubscriber *the_sub;
00428 bool in_stream;
00429 #endif
00430
00431 #ifdef AMIGA
00432 static void sub_invoc(void);
00433 void sub_func(void);
00434 struct Process *sound_process;
00435 int quit_sig, pause_sig,
00436 resume_sig, ahi_sig;
00437 struct Task *main_task;
00438 int main_sig;
00439 static ULONG sound_func(void);
00440 struct MsgPort *ahi_port;
00441 struct AHIRequest *ahi_io;
00442 struct AHIAudioCtrl *ahi_ctrl;
00443 struct AHISampleInfo sample[2];
00444 struct Hook sf_hook;
00445 int play_buf;
00446 #endif
00447
00448 #ifdef __linux__
00449 int devfd, sndbufsize, buffer_rate;
00450 int16 *sound_buffer;
00451 #endif
00452
00453 #ifdef SUN
00454 int fd;
00455 audio_info status;
00456 uint_t sent_samples,delta_samples;
00457 WORD *sound_calc_buf;
00458 #endif
00459
00460 #ifdef __hpux
00461 int fd;
00462 audio_status status;
00463 int16 * sound_calc_buf;
00464 int linecnt;
00465 #endif
00466
00467 #ifdef __mac__
00468 SndChannelPtr chan1;
00469 SndDoubleBufferHeader myDblHeader;
00470 SndDoubleBufferPtr sampleBuffer1, sampleBuffer2;
00471 SCStatus myStatus;
00472 short sndbufsize;
00473 OSErr err;
00474
00475 static void doubleBackProc(SndChannelPtr chan, SndDoubleBufferPtr doubleBuffer);
00476 #endif
00477
00478 #ifdef WIN32
00479 public:
00480 void VBlank(void);
00481
00482 private:
00483 void StartPlayer(void);
00484 void StopPlayer(void);
00485
00486 BOOL direct_sound;
00487 DigitalPlayer *ThePlayer;
00488 SWORD *sound_buffer;
00489 int to_output;
00490 int sb_pos;
00491 int divisor;
00492 int *lead;
00493 int lead_pos;
00494 #endif
00495
00496 #ifdef __riscos__
00497 int linecnt, sndbufsize;
00498 uint8 *sound_buffer;
00499 #endif
00500
00501 private:
00502 uint8 sid_random();
00503 private:
00504 C64 *the_c64;
00505
00506 #ifndef GLOBAL_PREFS
00507 Prefs& ThePrefs;
00508 #endif
00509
00510 uint32 seed;
00511
00512 #ifdef __SYMBIAN32__
00513
00514 #ifndef __ER6__
00515 RDevSound iDevSound;
00516 HBufC8* iAlawBuffer;
00517 #else // __ER6__
00518
00519 public:
00520
00521 void MaoscOpenComplete(TInt aError);
00522 void MaoscBufferCopied(TInt aError, const TDesC8& aBuffer);
00523 void MaoscPlayComplete(TInt aError);
00524
00525 void reset_sync();
00526 void SetVolumeL(TInt aVolume);
00527
00528 public:
00529 CMdaAudioOutputStream* iStream;
00530 TMdaAudioDataSettings iSettings;
00531
00532
00533 TUint iStartPlayTickCount;
00534 TUint iCountSampleBlocksCopied;
00535 TInt iTickPeriod_ys;
00536 TBool iAudioStarvation;
00537 TPtrC8 sound_buffer_desc;
00538
00539 #endif // __ER6__
00540 int16 *sound_buffer;
00541
00542 int divisor;
00543 int to_output;
00544 int buffer_pos;
00545
00546
00547 inline void InitFixSinTab(void);
00548 inline FixPoint fixsin(FixPoint x);
00549 inline FixPoint fixcos(FixPoint x);
00550 FixPoint SinTable[(1<<ldSINTAB)];
00551
00552 #endif // __SYMBIAN32__
00553
00554 };
00555
00559 uint8 DigitalRenderer::sid_random()
00560 {
00561 seed = seed * 1103515245 + 12345;
00562 return seed >> 16;
00563 }
00564
00565 #ifndef EMUL_MOS8580
00566
00567 const uint16 DigitalRenderer::TriSawTable[0x100] = {
00568 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00569 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00570 0x0000, 0x0000, 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, 0x0808,
00576 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00577 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00578 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00579 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00580 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
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, 0x1010, 0x3C3C,
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, 0x0808,
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, 0x0000,
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, 0x1010, 0x3C3C
00600 };
00601
00602 const uint16 DigitalRenderer::TriRectTable[0x100] = {
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, 0x0000,
00613 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00614 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00615 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00616 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00617 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0xC0C0,
00618 0x0000, 0x8080, 0x8080, 0xE0E0, 0x8080, 0xE0E0, 0xF0F0, 0xFCFC,
00619 0xFFFF, 0xFCFC, 0xFAFA, 0xF0F0, 0xF6F6, 0xE0E0, 0xE0E0, 0x8080,
00620 0xEEEE, 0xE0E0, 0xE0E0, 0x8080, 0xC0C0, 0x0000, 0x0000, 0x0000,
00621 0xDEDE, 0xC0C0, 0xC0C0, 0x0000, 0x8080, 0x0000, 0x0000, 0x0000,
00622 0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00623 0xBEBE, 0x8080, 0x8080, 0x0000, 0x8080, 0x0000, 0x0000, 0x0000,
00624 0x8080, 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 0x7E7E, 0x4040, 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 };
00636
00637 const uint16 DigitalRenderer::SawRectTable[0x100] = {
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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00649 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00650 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00651 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00652 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00653 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7878,
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, 0x0000,
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, 0x0000, 0x0000,
00668 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00669 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x7878
00670 };
00671
00672 const uint16 DigitalRenderer::TriSawRectTable[0x100] = {
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, 0x0000,
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, 0x0000, 0x0000, 0x0000, 0x0000,
00682 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00683 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00684 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00685 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00686 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
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 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00704 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
00705 };
00706 #else
00707
00708 const uint16 DigitalRenderer::TriSawTable[0x100] = {
00709 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00710 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00711 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x0808,
00717 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00718 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00719 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00720 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00721 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
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, 0x1818, 0x3C3C,
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, 0x1C1C,
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, 0x8080, 0x0000, 0x8080, 0x8080,
00739 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xE0E0,
00740 0xF0F0, 0xF0F0, 0xF0F0, 0xF0F0, 0xF8F8, 0xF8F8, 0xFCFC, 0xFEFE
00741 };
00742
00743 const uint16 DigitalRenderer::TriRectTable[0x100] = {
00744 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00745 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00746 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00747 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00748 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00749 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00750 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00751 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00752 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00753 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00754 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00755 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00756 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
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 0xFFFF, 0xFCFC, 0xF8F8, 0xF0F0, 0xF4F4, 0xF0F0, 0xF0F0, 0xE0E0,
00761 0xECEC, 0xE0E0, 0xE0E0, 0xC0C0, 0xE0E0, 0xC0C0, 0xC0C0, 0xC0C0,
00762 0xDCDC, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0x8080, 0x8080,
00763 0xC0C0, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x0000, 0x0000,
00764 0xBEBE, 0xA0A0, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x0000,
00765 0x8080, 0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00766 0x8080, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00767 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00768 0x7E7E, 0x7070, 0x6060, 0x0000, 0x4040, 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 };
00777
00778 const uint16 DigitalRenderer::SawRectTable[0x100] = {
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, 0x0000, 0x0000,
00787 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00788 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00789 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00790 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00791 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00792 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00793 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00794 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00795 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00796 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00797 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00798 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00799 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00800 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00801 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0x8080,
00802 0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xB0B0, 0xBEBE,
00803 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080,
00804 0x0000, 0x0000, 0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0,
00805 0x0000, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0,
00806 0x8080, 0x8080, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xDCDC,
00807 0x8080, 0x8080, 0x8080, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0, 0xC0C0,
00808 0xC0C0, 0xC0C0, 0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xE0E0, 0xECEC,
00809 0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xE0E0, 0xF0F0, 0xF0F0, 0xF4F4,
00810 0xF0F0, 0xF0F0, 0xF8F8, 0xF8F8, 0xF8F8, 0xFCFC, 0xFEFE, 0xFFFF
00811 };
00812
00813 const uint16 DigitalRenderer::TriSawRectTable[0x100] = {
00814 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00815 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00816 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00817 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00818 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00819 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00820 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00821 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00822 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00823 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00824 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00825 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00826 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00828 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00829 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00830 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00831 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00832 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00833 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00834 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00835 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00836 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00837 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00838 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00839 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00840 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00841 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00842 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
00843 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x8080, 0x8080,
00844 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0x8080, 0xC0C0, 0xC0C0,
00845 0xC0C0, 0xC0C0, 0xE0E0, 0xE0E0, 0xE0E0, 0xF0F0, 0xF8F8, 0xFCFC
00846 };
00847 #endif
00848
00849 const uint32 DigitalRenderer::EGTable[16] = {
00850 (SID_CYCLES << 16) / 9, (SID_CYCLES << 16) / 32,
00851 (SID_CYCLES << 16) / 63, (SID_CYCLES << 16) / 95,
00852 (SID_CYCLES << 16) / 149, (SID_CYCLES << 16) / 220,
00853 (SID_CYCLES << 16) / 267, (SID_CYCLES << 16) / 313,
00854 (SID_CYCLES << 16) / 392, (SID_CYCLES << 16) / 977,
00855 (SID_CYCLES << 16) / 1954, (SID_CYCLES << 16) / 3126,
00856 (SID_CYCLES << 16) / 3906, (SID_CYCLES << 16) / 11720,
00857 (SID_CYCLES << 16) / 19531, (SID_CYCLES << 16) / 31251
00858 };
00859
00860 const uint8 DigitalRenderer::EGDRShift[256] = {
00861 5,5,5,5,5,5,5,5,4,4,4,4,4,4,4,4,
00862 3,3,3,3,3,3,3,3,3,3,3,3,2,2,2,2,
00863 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
00864 2,2,2,2,2,2,2,2,1,1,1,1,1,1,1,1,
00865 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00866 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
00867 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00868 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00869 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00870 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00871 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00872 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00873 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00874 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00875 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
00876 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
00877 };
00878
00879 const int16 DigitalRenderer::SampleTab[16] = {
00880 0x8000, 0x9111, 0xa222, 0xb333, 0xc444, 0xd555, 0xe666, 0xf777,
00881 0x0888, 0x1999, 0x2aaa, 0x3bbb, 0x4ccc, 0x5ddd, 0x6eee, 0x7fff,
00882 };
00883
00884
00885
00886
00887
00888
00889 DigitalRenderer::DigitalRenderer(C64 *c64)
00890 :the_c64(c64)
00891 ,ThePrefs(c64->ThePrefs)
00892 ,seed(1)
00893 {
00894 __CHECK_NULL(c64);
00895
00896 CTOR(DigitalRenderer);
00897
00898
00899 voice[0].mod_by = &voice[2];
00900 voice[1].mod_by = &voice[0];
00901 voice[2].mod_by = &voice[1];
00902 voice[0].mod_to = &voice[1];
00903 voice[1].mod_to = &voice[2];
00904 voice[2].mod_to = &voice[0];
00905
00906
00907 for (int i=0; i<0x1000; i++) {
00908 TriTable[i] = (i << 4) | (i >> 8);
00909 TriTable[0x1fff-i] = (i << 4) | (i >> 8);
00910 }
00911
00912 #ifdef PRECOMPUTE_RESONANCE
00913 #ifdef USE_FIXPOINT_MATHS
00914
00915 for (int j=0; j<256; j++) {
00916 resonanceLP[j] = FixNo(CALC_RESONANCE_LP(j));
00917 resonanceHP[j] = FixNo(CALC_RESONANCE_HP(j));
00918 }
00919
00920 sidquot = (int32)((((double)SID_FREQ)*65536) / SAMPLE_FREQ);
00921
00922
00923 #else
00924 for (int j=0; j<256; j++) {
00925 resonanceLP[j] = CALC_RESONANCE_LP(j);
00926 resonanceHP[j] = CALC_RESONANCE_HP(j);
00927 }
00928 #endif
00929 #endif
00930
00931 #ifdef USE_FIXPOINT_MATHS
00932 InitFixSinTab();
00933 #endif
00934
00935 Reset();
00936
00937
00938 init_sound();
00939 }
00940
00941
00942
00943
00944
00945
00946 void DigitalRenderer::Reset(void)
00947 {
00948 volume = 0;
00949 v3_mute = false;
00950
00951 for (int v=0; v<3; v++) {
00952 voice[v].wave = WAVE_NONE;
00953 voice[v].eg_state = EG_IDLE;
00954 voice[v].count = voice[v].add = 0;
00955 voice[v].freq = voice[v].pw = 0;
00956 voice[v].eg_level = voice[v].s_level = 0;
00957 voice[v].a_add = voice[v].d_sub = voice[v].r_sub = EGTable[0];
00958 voice[v].gate = voice[v].ring = voice[v].test = false;
00959 voice[v].filter = voice[v].sync = false;
00960 }
00961
00962 f_type = FILT_NONE;
00963 f_freq = f_res = 0;
00964 #ifdef USE_FIXPOINT_MATHS
00965 f_ampl = FixNo(1);
00966 d1 = d2 = g1 = g2 = 0;
00967 xn1 = xn2 = yn1 = yn2 = 0;
00968 #else
00969 f_ampl = 1.0;
00970 d1 = d2 = g1 = g2 = 0.0;
00971 xn1 = xn2 = yn1 = yn2 = 0.0;
00972 #endif
00973
00974 sample_in_ptr = 0;
00975 memset(sample_buf, 0, SAMPLE_BUF_SIZE);
00976
00977 ELOG1(_L8("Digital renderer reset\n"));
00978
00979 }
00980
00981
00982
00983
00984
00985
00986 void DigitalRenderer::WriteRegister(uint16 adr, uint8 byte)
00987 {
00988 if (!ready)
00989 return;
00990
00991 int v = adr/7;
00992
00993 switch (adr) {
00994 case 0:
00995 case 7:
00996 case 14:
00997 voice[v].freq = (voice[v].freq & 0xff00) | byte;
00998 #ifdef USE_FIXPOINT_MATHS
00999 voice[v].add = sidquot.imul((int)voice[v].freq);
01000 #else
01001 voice[v].add = (uint32)((float)voice[v].freq * SID_FREQ / SAMPLE_FREQ);
01002 #endif
01003 break;
01004
01005 case 1:
01006 case 8:
01007 case 15:
01008 voice[v].freq = (voice[v].freq & 0xff) | (byte << 8);
01009 #ifdef USE_FIXPOINT_MATHS
01010 voice[v].add = sidquot.imul((int)voice[v].freq);
01011 #else
01012 voice[v].add = (uint32)((float)voice[v].freq * SID_FREQ / SAMPLE_FREQ);
01013 #endif
01014 break;
01015
01016 case 2:
01017 case 9:
01018 case 16:
01019 voice[v].pw = (voice[v].pw & 0x0f00) | byte;
01020 break;
01021
01022 case 3:
01023 case 10:
01024 case 17:
01025 voice[v].pw = (voice[v].pw & 0xff) | ((byte & 0xf) << 8);
01026 break;
01027
01028 case 4:
01029 case 11:
01030 case 18:
01031 voice[v].wave = (byte >> 4) & 0xf;
01032 if ((byte & 1) != voice[v].gate)
01033 if (byte & 1)
01034 voice[v].eg_state = EG_ATTACK;
01035 else
01036 if (voice[v].eg_state != EG_IDLE)
01037 voice[v].eg_state = EG_RELEASE;
01038 voice[v].gate = byte & 1;
01039 voice[v].mod_by->sync = byte & 2;
01040 voice[v].ring = byte & 4;
01041 if ((voice[v].test = byte & 8))
01042 voice[v].count = 0;
01043 break;
01044
01045 case 5:
01046 case 12:
01047 case 19:
01048 voice[v].a_add = EGTable[byte >> 4];
01049 voice[v].d_sub = EGTable[byte & 0xf];
01050 break;
01051
01052 case 6:
01053 case 13:
01054 case 20:
01055 voice[v].s_level = (byte >> 4) * 0x111111;
01056 voice[v].r_sub = EGTable[byte & 0xf];
01057 break;
01058
01059 case 22:
01060 if (byte != f_freq) {
01061 f_freq = byte;
01062 if (ThePrefs.SIDFilters)
01063 calc_filter();
01064 }
01065 break;
01066
01067 case 23:
01068 voice[0].filter = byte & 1;
01069 voice[1].filter = byte & 2;
01070 voice[2].filter = byte & 4;
01071 if ((byte >> 4) != f_res) {
01072 f_res = byte >> 4;
01073 if (ThePrefs.SIDFilters)
01074 calc_filter();
01075 }
01076 break;
01077
01078 case 24:
01079 volume = byte & 0xf;
01080 v3_mute = byte & 0x80;
01081 if (((byte >> 4) & 7) != f_type) {
01082 f_type = (byte >> 4) & 7;
01083 #ifdef USE_FIXPOINT_MATHS
01084 xn1 = xn2 = yn1 = yn2 = 0;
01085 #else
01086 xn1 = xn2 = yn1 = yn2 = 0.0;
01087 #endif
01088 if (ThePrefs.SIDFilters)
01089 calc_filter();
01090 }
01091 break;
01092 }
01093 }
01094
01095
01096
01097
01098
01099
01100 void DigitalRenderer::NewPrefs(Prefs *prefs)
01101 {
01102 calc_filter();
01103
01104 #if defined(__SYMBIAN32__)
01105 if(!prefs)
01106 return;
01107 #if !defined (__ER6__)
01108
01109 TSoundCaps sndCaps;
01110 iDevSound.Caps(sndCaps);
01111 if(prefs->iVolume > sndCaps().iMaxVolume)
01112 prefs->iVolume = sndCaps().iMaxVolume;
01113 else if(prefs->iVolume < 0)
01114 prefs->iVolume = 0;
01115
01116 TSoundConfig sndConfig;
01117 iDevSound.Config(sndConfig);
01118
01119 sndConfig().iVolumeValue = prefs->iVolume;
01120
01121 const TInt ret = iDevSound.SetConfig(sndConfig);
01122 if(ret != KErrNone)
01123 {
01124 ELOG2(_L8("AUDIO: WARNING! Could not set config due to [%d]\n"), ret);
01125 }
01126
01127 #else
01128
01129 SetVolumeL(prefs->iVolume);
01130
01131 #endif // !defined (__ER6__)
01132 #endif // __SYMBIAN32__
01133 }
01134
01135
01136
01137
01138
01139
01140 void DigitalRenderer::calc_filter(void)
01141 {
01142 #ifdef USE_FIXPOINT_MATHS
01143 FixPoint fr, arg;
01144
01145 if (f_type == FILT_ALL)
01146 {
01147 d1 = 0; d2 = 0; g1 = 0; g2 = 0; f_ampl = FixNo(1); return;
01148 }
01149 else if (f_type == FILT_NONE)
01150 {
01151 d1 = 0; d2 = 0; g1 = 0; g2 = 0; f_ampl = 0; return;
01152 }
01153 #else
01154 float fr, arg;
01155
01156
01157 if (f_type == FILT_ALL) {
01158 d1 = 0.0; d2 = 0.0;
01159 g1 = 0.0; g2 = 0.0;
01160 f_ampl = 1.0;
01161 return;
01162 } else if (f_type == FILT_NONE) {
01163 d1 = 0.0; d2 = 0.0;
01164 g1 = 0.0; g2 = 0.0;
01165 f_ampl = 0.0;
01166 return;
01167 }
01168 #endif
01169
01170
01171 if (f_type == FILT_LP || f_type == FILT_LPBP)
01172 #ifdef PRECOMPUTE_RESONANCE
01173 fr = resonanceLP[f_freq];
01174 #else
01175 fr = CALC_RESONANCE_LP(f_freq);
01176 #endif
01177 else
01178 #ifdef PRECOMPUTE_RESONANCE
01179 fr = resonanceHP[f_freq];
01180 #else
01181 fr = CALC_RESONANCE_HP(f_freq);
01182 #endif
01183
01184 #ifdef USE_FIXPOINT_MATHS
01185
01186 arg = fr / (int)(SAMPLE_FREQ >> 1);
01187 if (arg > FixNo(0.99)) {arg = FixNo(0.99);}
01188 if (arg < FixNo(0.01)) {arg = FixNo(0.01);}
01189
01190 g2 = FixNo(0.55) + FixNo(1.2) * arg * (arg - 1) + FixNo(0.0133333333) * (int)f_res;
01191
01192
01193 g1 = FixNo(-2) * g2.sqrt() * fixcos(arg);
01194
01195
01196
01197 if (f_type == FILT_LPBP || f_type == FILT_HPBP) {g2 += FixNo(0.1);}
01198
01199
01200
01201 if (g1.abs() >= g2 + 1)
01202 {
01203 if (g1 > 0) {g1 = g2 + FixNo(0.99);}
01204 else {g1 = -(g2 + FixNo(0.99));}
01205 }
01206
01207 switch (f_type)
01208 {
01209 case FILT_LPBP:
01210 case FILT_LP:
01211 d1 = FixNo(2); d2 = FixNo(1); f_ampl = FixNo(0.25) * (1 + g1 + g2); break;
01212 case FILT_HPBP:
01213 case FILT_HP:
01214 d1 = FixNo(-2); d2 = FixNo(1); f_ampl = FixNo(0.25) * (1 - g1 + g2); break;
01215 case FILT_BP:
01216
01217 d1 = 0; d2 = FixNo(-1);
01218 f_ampl = FixNo(0.25) * (1 + g1 + g2) * (1 + fixcos(arg)) / fixsin(arg);
01219 break;
01220 case FILT_NOTCH:
01221
01222 d1 = FixNo(-2) * fixcos(arg); d2 = FixNo(1);
01223 f_ampl = FixNo(0.25) * (1 + g1 + g2) * (1 + fixcos(arg)) / fixsin(arg);
01224 break;
01225 default: break;
01226 }
01227
01228 #else // USE_FIXPOINT_MATHS
01229
01230
01231 arg = fr / (float)(SAMPLE_FREQ >> 1);
01232 if (arg > 0.99)
01233 arg = 0.99;
01234 if (arg < 0.01)
01235 arg = 0.01;
01236
01237
01238 g2 = 0.55 + 1.2 * arg * arg - 1.2 * arg + (float)f_res * 0.0133333333;
01239 g1 = -2.0 * sqrt(g2) * cos(M_PI * arg);
01240
01241
01242 if (f_type == FILT_LPBP || f_type == FILT_HPBP)
01243 g2 += 0.1;
01244
01245
01246 if (fabs(g1) >= g2 + 1.0)
01247 if (g1 > 0.0)
01248 g1 = g2 + 0.99;
01249 else
01250 g1 = -(g2 + 0.99);
01251
01252
01253 switch (f_type) {
01254
01255 case FILT_LPBP:
01256 case FILT_LP:
01257 d1 = 2.0; d2 = 1.0;
01258 f_ampl = 0.25 * (1.0 + g1 + g2);
01259 break;
01260
01261 case FILT_HPBP:
01262 case FILT_HP:
01263 d1 = -2.0; d2 = 1.0;
01264 f_ampl = 0.25 * (1.0 - g1 + g2);
01265 break;
01266
01267 case FILT_BP:
01268 d1 = 0.0; d2 = -1.0;
01269 f_ampl = 0.25 * (1.0 + g1 + g2) * (1 + cos(M_PI * arg)) / sin(M_PI * arg);
01270 break;
01271
01272 case FILT_NOTCH:
01273 d1 = -2.0 * cos(M_PI * arg); d2 = 1.0;
01274 f_ampl = 0.25 * (1.0 + g1 + g2) * (1 + cos(M_PI * arg)) / (sin(M_PI * arg));
01275 break;
01276
01277 default:
01278 break;
01279 }
01280 #endif // USE_FIXPOINT_MATHS
01281 }
01282
01283
01287 #if defined(__riscos__)
01288 void DigitalRenderer::calc_buffer(uint8 *buf, long count)
01289 #else
01290 void DigitalRenderer::calc_buffer(int16 *buf, long count)
01291 #endif
01292 {
01293
01294
01295 #ifdef USE_FIXPOINT_MATHS
01296 FixPoint cf_ampl = f_ampl;
01297 FixPoint cd1 = d1, cd2 = d2, cg1 = g1, cg2 = g2;
01298 #else
01299 float cf_ampl = f_ampl;
01300 float cd1 = d1, cd2 = d2, cg1 = g1, cg2 = g2;
01301 #endif
01302
01303 #ifdef __riscos__
01304 uint8 *LinToLog, *LogScale;
01305 #endif
01306
01307
01308 uint32 sample_count = (sample_in_ptr + SAMPLE_BUF_SIZE/2) << 16;
01309
01310 #ifdef __riscos__ // on RISC OS we have 8 bit logarithmic sound
01311 DigitalRenderer_GetTables(&LinToLog, &LogScale);
01312 #else
01313 #ifdef __BEOS__
01314 count >>= 2;
01315 #else
01316 count >>= 1;
01317 #endif
01318 #endif
01319 while (count--) {
01320 int32 sum_output;
01321 int32 sum_output_filter = 0;
01322
01323
01324
01325 uint8 master_volume = sample_buf[(sample_count >> 16) % SAMPLE_BUF_SIZE];
01326 sample_count += ((0x138 * 50) << 16) / SAMPLE_FREQ;
01327 sum_output = SampleTab[master_volume] << 8;
01328
01329
01330 for (int j=0; j<3; j++) {
01331 DRVoice *v = &voice[j];
01332
01333
01334 uint16 envelope;
01335
01336 switch (v->eg_state) {
01337 case EG_ATTACK:
01338 v->eg_level += v->a_add;
01339 if (v->eg_level > 0xffffff) {
01340 v->eg_level = 0xffffff;
01341 v->eg_state = EG_DECAY;
01342 }
01343 break;
01344 case EG_DECAY:
01345 if (v->eg_level <= v->s_level || v->eg_level > 0xffffff)
01346 v->eg_level = v->s_level;
01347 else {
01348 v->eg_level -= v->d_sub >> EGDRShift[v->eg_level >> 16];
01349 if (v->eg_level <= v->s_level || v->eg_level > 0xffffff)
01350 v->eg_level = v->s_level;
01351 }
01352 break;
01353 case EG_RELEASE:
01354 v->eg_level -= v->r_sub >> EGDRShift[v->eg_level >> 16];
01355 if (v->eg_level > 0xffffff) {
01356 v->eg_level = 0;
01357 v->eg_state = EG_IDLE;
01358 }
01359 break;
01360 case EG_IDLE:
01361 v->eg_level = 0;
01362 break;
01363 }
01364 envelope = (v->eg_level * master_volume) >> 20;
01365
01366
01367 uint16 output;
01368
01369 if (!v->test)
01370 v->count += v->add;
01371
01372 if (v->sync && (v->count > 0x1000000))
01373 v->mod_to->count = 0;
01374
01375 v->count &= 0xffffff;
01376
01377 switch (v->wave) {
01378 case WAVE_TRI:
01379 if (v->ring)
01380 output = TriTable[(v->count ^ (v->mod_by->count & 0x800000)) >> 11];
01381 else
01382 output = TriTable[v->count >> 11];
01383 break;
01384 case WAVE_SAW:
01385 output = v->count >> 8;
01386 break;
01387 case WAVE_RECT:
01388 if (v->count > (uint32)(v->pw << 12))
01389 output = 0xffff;
01390 else
01391 output = 0;
01392 break;
01393 case WAVE_TRISAW:
01394 output = TriSawTable[v->count >> 16];
01395 break;
01396 case WAVE_TRIRECT:
01397 if (v->count > (uint32)(v->pw << 12))
01398 output = TriRectTable[v->count >> 16];
01399 else
01400 output = 0;
01401 break;
01402 case WAVE_SAWRECT:
01403 if (v->count > (uint32)(v->pw << 12))
01404 output = SawRectTable[v->count >> 16];
01405 else
01406 output = 0;
01407 break;
01408 case WAVE_TRISAWRECT:
01409 if (v->count > (uint32)(v->pw << 12))
01410 output = TriSawRectTable[v->count >> 16];
01411 else
01412 output = 0;
01413 break;
01414 case WAVE_NOISE:
01415 if (v->count > 0x100000) {
01416 output = v->noise = sid_random() << 8;
01417 v->count &= 0xfffff;
01418 } else
01419 output = v->noise;
01420 break;
01421 default:
01422 output = 0x8000;
01423 break;
01424 }
01425 if (v->filter)
01426 sum_output_filter += (int16)(output ^ 0x8000) * envelope;
01427 else
01428 sum_output += (int16)(output ^ 0x8000) * envelope;
01429 }
01430
01431
01432 if (ThePrefs.SIDFilters) {
01433 #ifdef USE_FIXPOINT_MATHS
01434 int32 xn = cf_ampl.imul(sum_output_filter);
01435 int32 yn = xn+cd1.imul(xn1)+cd2.imul(xn2)-cg1.imul(yn1)-cg2.imul(yn2);
01436 yn2 = yn1; yn1 = yn; xn2 = xn1; xn1 = xn;
01437 sum_output_filter = yn;
01438 #else
01439 float xn = (float)sum_output_filter * cf_ampl;
01440 float yn = xn + cd1 * xn1 + cd2 * xn2 - cg1 * yn1 - cg2 * yn2;
01441 yn2 = yn1; yn1 = yn; xn2 = xn1; xn1 = xn;
01442 sum_output_filter = (int32)yn;
01443 #endif
01444 }
01445
01446
01447 #ifdef __BEOS__
01448 int16 audio_data = (sum_output + sum_output_filter) >> 10;
01449 int val = *buf + audio_data;
01450 if (val > 32767)
01451 val = 32767;
01452 if (val < -32768)
01453 val = -32768;
01454 *buf++ = val;
01455 val = *buf + audio_data;
01456 if (val > 32767)
01457 val = 32767;
01458 if (val < -32768)
01459 val = -32768;
01460 *buf++ = val;
01461 #elif defined(__riscos__) // lookup in 8k (13bit) translation table
01462 *buf++ = LinToLog[((sum_output + sum_output_filter) >> 13) & 0x1fff];
01463 #else
01464 *buf++ = (sum_output + sum_output_filter) >> 10;
01465 #endif
01466 }
01467 }
01468
01469
01470
01471 #if defined(__SYMBIAN32__) // must be before __linux__ in case of using the GnuPoc SDK
01472 #include "sid_epoc32.i"
01473
01474 #elif defined(__BEOS__)
01475 #include "SID_Be.i"
01476
01477 #elif defined(AMIGA)
01478 #include "SID_Amiga.i"
01479
01480 #elif defined(__linux__)
01481 #include "SID_linux.i"
01482
01483 #elif defined(SUN)
01484 #include "SID_sun.i"
01485
01486 #elif defined(__hpux)
01487 #include "SID_hp.i"
01488
01489 #elif defined(__mac__)
01490 #include "SID_mac.i"
01491
01492 #elif defined(WIN32)
01493 #include "SID_WIN32.i"
01494
01495 #elif defined(__riscos__)
01496 #include "SID_Acorn.i"
01497
01498 #else // No sound
01499 void DigitalRenderer::init_sound(void) {ready = false;}
01500 DigitalRenderer::~DigitalRenderer()
01501 {
01502 DTOR(DigitalRenderer);
01503 }
01504 void DigitalRenderer::EmulateLine(void) {}
01505 void DigitalRenderer::Pause(void) {}
01506 void DigitalRenderer::Resume(void) {}
01507 #endif
01508
01509
01510
01511
01512
01513
01514 void MOS6581::open_close_renderer(int old_type, int new_type)
01515 {
01516 if (old_type == new_type)
01517 return;
01518
01519
01520 delete the_renderer;
01521
01522
01523 if (new_type == SIDTYPE_DIGITAL)
01524 the_renderer = new DigitalRenderer(the_c64);
01525
01526 #ifdef AMIGA
01527 else if (new_type == SIDTYPE_SIDCARD)
01528 the_renderer = new SIDCardRenderer();
01529 #endif
01530 else
01531 the_renderer = NULL;
01532
01533
01534 if (the_renderer != NULL)
01535 for (int i=0; i<25; i++)
01536 the_renderer->WriteRegister(i, regs[i]);
01537 }