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
00072
00073
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
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
00116 open_close_renderer(SIDTYPE_NONE, ThePrefs.SIDType);
00117
00118 CTOR(MOS6581);
00119 }
00120
00121
00125 MOS6581::~MOS6581()
00126 {
00127
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
00144 if (the_renderer != NULL)
00145 the_renderer->Reset();
00146
00147 ELOG1(_L8("SID reset\n"));
00148 }
00149
00150
00151
00152
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
00165
00166
00167 void MOS6581::PauseSound(void)
00168 {
00169 if (the_renderer != NULL)
00170 the_renderer->Pause();
00171 }
00172
00173
00174
00175
00176
00177
00178 void MOS6581::ResumeSound(void)
00179 {
00180 if (the_renderer != NULL)
00181 the_renderer->Resume();
00182 }
00183
00184
00185
00186
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
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
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;
00275 #else
00276 const uint32 SAMPLE_FREQ = 44100;
00277 #endif
00278 const uint32 SID_FREQ = 985248;
00279 const uint32 CALC_FREQ = 50;
00280 const uint32 SID_CYCLES = SID_FREQ/SAMPLE_FREQ;
00281 const int SAMPLE_BUF_SIZE = 0x138*2;
00282
00283
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
00297 enum {
00298 EG_IDLE,
00299 EG_ATTACK,
00300 EG_DECAY,
00301 EG_RELEASE
00302 };
00303
00304
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
00317 struct DRVoice {
00318 int wave;
00319 int eg_state;
00320 DRVoice *mod_by;
00321 DRVoice *mod_to;
00322
00323 uint32 count;
00324 uint32 add;
00325
00326 uint16 freq;
00327 uint16 pw;
00328
00329 uint32 a_add;
00330 uint32 d_sub;
00331 uint32 s_level;
00332 uint32 r_sub;
00333 uint32 eg_level;
00334
00335 uint32 noise;
00336
00337 bool gate;
00338 bool ring;
00339 bool test;
00340 bool filter;
00341
00342
00343
00344 bool sync;
00345 };
00346
00347
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;
00370 uint8 volume;
00371 bool v3_mute;
00372
00373 uint16 TriTable[0x1000*2];
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];
00379 static const uint8 EGDRShift[256];
00380 static const int16 SampleTab[16];
00381
00382 DRVoice voice[3];
00383
00384 uint8 f_type;
00385 uint8 f_freq;
00386 uint8 f_res;
00387 #ifdef USE_FIXPOINT_MATHS
00388 FixPoint f_ampl;
00389 FixPoint d1, d2, g1, g2;
00390 int32 xn1, xn2, yn1, yn2;
00391 FixPoint sidquot;
00392 #ifdef PRECOMPUTE_RESONANCE
00393 FixPoint resonanceLP[256];
00394 FixPoint resonanceHP[256];
00395 #endif
00396 #else
00397 float f_ampl;
00398 float d1, d2, g1, g2;
00399 float xn1, xn2, yn1, yn2;
00400 #ifdef PRECOMPUTE_RESONANCE
00401 float resonanceLP[256];
00402 float resonanceHP[256];
00403 #endif
00404 #endif
00405
00406 uint8 sample_buf[SAMPLE_BUF_SIZE];
00407 int sample_in_ptr;
00408
00409 #ifdef __BEOS__
00410 static bool stream_func(void *arg, char *buf, size_t count, void *header);
00411 BDACStream *the_stream;
00412 BSubscriber *the_sub;
00413 bool in_stream;
00414 #endif
00415
00416 #ifdef AMIGA
00417 static void sub_invoc(void);
00418 void sub_func(void);
00419 struct Process *sound_process;
00420 int quit_sig, pause_sig,
00421 resume_sig, ahi_sig;
00422 struct Task *main_task;
00423 int main_sig;
00424 static ULONG sound_func(void);
00425 struct MsgPort *ahi_port;
00426 struct AHIRequest *ahi_io;
00427 struct AHIAudioCtrl *ahi_ctrl;
00428 struct AHISampleInfo sample[2];
00429 struct Hook sf_hook;
00430 int play_buf;
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:
00487 uint8 sid_random();
00488 private:
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
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
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
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
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
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
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
00861 sidquot = (int32)((((double)SID_FREQ)*65536) / SAMPLE_FREQ);
00862
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
00875 init_sound();
00876 }
00877
00878
00879
00880
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
00921
00922
00923 void DigitalRenderer::WriteRegister(uint16 adr, uint8 byte)
00924 {
00925 if (!ready)
00926 return;
00927
00928 int v = adr/7;
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)
00971 voice[v].eg_state = EG_ATTACK;
00972 else
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
01035
01036
01037 void DigitalRenderer::NewPrefs(Prefs *prefs)
01038 {
01039 calc_filter();
01040 }
01041
01042
01043
01044
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
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
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
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
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
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
01141 if (f_type == FILT_LPBP || f_type == FILT_HPBP)
01142 g2 += 0.1;
01143
01144
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
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
01193
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
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);
01211 #else
01212 #ifdef __BEOS__
01213 count >>= 2;
01214 #else
01215 count >>= 1;
01216 #endif
01217 #endif
01218 while (count--) {
01219 int32 sum_output;
01220 int32 sum_output_filter = 0;
01221
01222
01223
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
01229 for (int j=0; j<3; j++) {
01230 DRVoice *v = &voice[j];
01231
01232
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
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
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
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
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
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
01416 delete the_renderer;
01417
01418
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
01430 if (the_renderer != NULL)
01431 for (int i=0; i<25; i++)
01432 the_renderer->WriteRegister(i, regs[i]);
01433 }