64 static unsigned char exponential_delays[256];
67 #define getFrameCount() (sidemu->sFrameCount)
88 static inline int pfloat_ConvertFromInt(
int i) {
return (i<<16); }
89 static inline int pfloat_ConvertFromFloat(
float f) {
return (
int)(f*(1<<16)); }
90 static inline int pfloat_Multiply(
int a,
int b) {
return (a>>8)*(b>>8); }
91 static inline int pfloat_ConvertToInt(
int i) {
return (i>>16); }
95 static const int attackTimes[16] = {
96 2, 8, 16, 24, 38, 56, 68, 80, 100, 240, 500, 800, 1000, 3000, 5000, 8000
109 static inline unsigned char get_bit(
unsigned long val,
unsigned char b)
111 return (
unsigned char) ((val >> b) & 1);
122 static const signed char pulseTriangleWavetable[] =
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00,
125 0x00, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x10,
126 0x10, 0x00, 0x00, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x20,
127 0x10, 0x00, 0x06, 0x06, 0x06, 0x06, 0x0b, 0x15, 0x0b, 0x0b, 0x0b, 0x15, 0x25, 0x2f, 0x2f, 0x69,
128 0x20, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x0b, 0x15, 0x15,
129 0x1b, 0x06, 0x0b, 0x10, 0x0b, 0x0b, 0x15, 0x25, 0x15, 0x0b, 0x0b, 0x63, 0x49, 0x69, 0x88, 0x3a,
130 0x3a, 0x06, 0x0b, 0x06, 0x10, 0x10, 0x15, 0x3f, 0x10, 0x25, 0x59, 0x59, 0x3f, 0x9d, 0xa7, 0x59,
131 0x00, 0x00, 0x5e, 0x59, 0x88, 0xb7, 0xb7, 0xac, 0x83, 0xac, 0xd1, 0xc6, 0xc1, 0xdb, 0xdb, 0xeb,
146 static int clocksToSamples(
int clocks) {
147 #ifdef SID_USES_SAMPLE_ENV_COUNTER
148 return round(((
float)clocks)/cyclesPerSample)+1;
160 static unsigned char triggerLFSR_Threshold(
unsigned int threshold,
signed int *end) {
161 if (threshold == (*end)) {
171 static unsigned char handleExponentialDelay (
struct SidEmulation *sidemu,
unsigned char voice ) {
183 static void simOneEnvelopeCycle(
struct SidEmulation *sidemu,
unsigned char v ) {
220 if (triggerLFSR_Threshold(sidemu->
osc[v].
decay, &sidemu->
osc[v].
currentLFSR) && handleExponentialDelay(sidemu, v)) {
239 if (triggerLFSR_Threshold(sidemu->
osc[v].
release, &sidemu->
osc[v].
currentLFSR) && handleExponentialDelay(sidemu, v)) {
268 unsigned char sustain= sidemu->
sid.
v[v].
sr >> 4;
269 sidemu->
osc[v].
sustain = sustain<<4 | sustain;
275 #ifdef SID_USES_FILTER
279 if (sidemu->
filter.
freq>pfloat_ConvertFromInt(1)) {
294 sidemu->
filter.
rez = (pfloat_ConvertFromFloat(1.2f) -
295 pfloat_ConvertFromFloat(0.04f)*(sidemu->
sid.
res_ftv >> 4)) >> 8;
298 for (bp=0;bp<len;bp+=
step) {
308 if (sidemu->
osc[v].
wave & 0x08) {
314 unsigned char refosc = v?v-1:2;
316 if (sidemu->
osc[v].
wave & 0x02)
320 unsigned char tripos = (
unsigned char) (sidemu->
osc[v].
counter>>19);
321 unsigned char triout= tripos;
325 unsigned char sawout = (
unsigned char) (sidemu->
osc[v].
counter >> 20);
326 unsigned char plsout = (
unsigned char) ((sidemu->
osc[v].
counter > sidemu->
osc[v].
pulse)-1);
334 if ((sidemu->
osc[v].
wave & 0x40) && (sidemu->
osc[v].
wave & 0x10)) {
361 if (sidemu->
osc[v].
wave & 0x04)
372 unsigned char outv=0xFF;
374 if ((0x1 << v) & voiceEnableMask) {
376 if ((sidemu->
osc[v].
wave & 0x40) && (sidemu->
osc[v].
wave & 0x10)) {
380 unsigned char idx= tripos > 0x7f ? 0xff-tripos : tripos;
381 outv &= pulseTriangleWavetable[idx];
385 if ((sidemu->
osc[v].
wave & 0x10) && ++updated) outv &= triout;
386 if ((sidemu->
osc[v].
wave & 0x20) && ++updated) outv &= sawout;
387 if ((sidemu->
osc[v].
wave & 0x40) && ++updated) outv &= plsout;
388 if ((sidemu->
osc[v].
wave & 0x80) && ++updated) outv &= nseout;
389 if (!updated) outv &= sidemu->
level_DC;
396 #ifdef SID_USES_SAMPLE_ENV_COUNTER
398 simOneEnvelopeCycle(v);
402 unsigned int cycles= (
unsigned int)c;
406 for (i= 0; i<cycles; i++) {
407 simOneEnvelopeCycle(sidemu, v);
413 #ifdef SID_USES_FILTER
423 if (!sMuteVoice[v]) outf+= (int)(((
signed short)(outv-0x80)) * (sidemu->
osc[v].
envelopeOutput));
427 #ifdef SID_USES_FILTER
454 int final_sample = (sidemu->
filter.
vol*(outo+outf));
456 int final_sample = outf>>2;
462 const int clipValue = 32767;
463 if ( final_sample < -clipValue ) {
464 final_sample = -clipValue;
465 }
else if ( final_sample > clipValue ) {
466 final_sample = clipValue;
469 short out= final_sample;
475 static char hex1 [16]= {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
476 static char *pokeInfo;
478 static void traceSidPoke(
int reg,
unsigned char val) {
479 pokeInfo= malloc(
sizeof(
char)*13);
481 pokeInfo[0]= hex1[(sFrameCount>>12)&0xf];
482 pokeInfo[1]= hex1[(sFrameCount>>8)&0xf];
483 pokeInfo[2]= hex1[(sFrameCount>>4)&0xf];
484 pokeInfo[3]= hex1[(sFrameCount&0xf)];
488 pokeInfo[7]= hex1[(reg>>4)];
489 pokeInfo[8]= hex1[(reg&0xf)];
491 pokeInfo[10]= hex1[(val>>4)];
492 pokeInfo[11]= hex1[(val&0xf)];
494 fprintf(stderr,
"%s\n", pokeInfo);
504 static void incFrameCount() {
522 if ((reg >= 7) && (reg <=13)) {voice=1; reg-=7;}
523 if ((reg >= 14) && (reg <=20)) {voice=2; reg-=14;}
539 unsigned char oldGate= sidemu->
sid.
v[voice].
wave&0x1;
540 unsigned char oldTest= sidemu->
sid.
v[voice].
wave&0x8;
541 unsigned char newGate= val & 0x01;
545 if (oldTest && (val&0x8) && !oldGate && newGate) {
549 if (!oldGate && newGate) {
554 }
else if (oldGate && !newGate) {
563 sidemu->
sid.
v[voice].
ad = val;
574 case 6: sidemu->
sid.
v[voice].
sr = val;
break;
585 static void simOsc3Polling(
unsigned short ad) {
588 unsigned int t=(16777216/
sid.v[2].freq)>>8;
589 unsigned long usedCycles= sidemu->
sCycles;
590 if (sLastPolledOsc < usedCycles) {
591 usedCycles-= sLastPolledOsc;
594 sidemu->
sCycles+= (t-usedCycles);
596 sLastPolledOsc= sidemu->
sCycles;
602 static void resetEngine (
struct SidEmulation *sidemu,
unsigned long mixfrq,
unsigned level_dc )
605 sidemu->
freqmul = 15872000 / mixfrq;
606 sidemu->
filtmul = pfloat_ConvertFromFloat(21.5332031f)/mixfrq;
607 memset((
unsigned char*)&sidemu->
sid,0,
sizeof(
struct SidRegisters));
608 memset((
unsigned char*)&sidemu->
osc[0],0,
sizeof(
struct SidOsc));
609 memset((
unsigned char*)&sidemu->
osc[1],0,
sizeof(
struct SidOsc));
610 memset((
unsigned char*)&sidemu->
osc[2],0,
sizeof(
struct SidOsc));
611 memset((
unsigned char*)&sidemu->
filter,0,
sizeof(
struct SidFilter));
633 sidemu->voiceEnableMask = 0x7;
661 #ifdef SID_USES_SAMPLE_ENV_COUNTER
663 for (
int i=0; i<16; i++) {
665 sidemu->
envelope_counter_period[i]= (int)round((
float)(attackTimes[i]*cyclesPerSec)/1000/256/cyclesPerSample)+1;
670 for (
int i=0; i<16; i++) {
677 static const unsigned char from[] = {93, 54, 26, 14, 6, 0};
678 static const unsigned char val[] = { 1, 2, 4, 8, 16, 30};
679 for (
int i = 0; i<256; i++) {
682 for (j= 0; j<6; j++) {
688 exponential_delays[i]= v;
698 #ifdef XEMU_SNAPSHOT_SUPPORT
702 #define SNAPSHOT_SID_BLOCK_VERSION 0
703 #define SNAPSHOT_SID_BLOCK_SIZE 256
705 int sid_snapshot_load_state (
const struct xemu_snapshot_definition_st *def,
struct xemu_snapshot_block_st *
block )
707 Uint8 buffer[SNAPSHOT_SID_BLOCK_SIZE];
710 if (
block->block_version != SNAPSHOT_SID_BLOCK_VERSION ||
block->sub_counter ||
block->sub_size !=
sizeof buffer)
711 RETURN_XSNAPERR_USER(
"Bad CIA block syntax");
712 a = xemusnap_read_file(buffer,
sizeof buffer);
721 int sid_snapshot_save_state (
const struct xemu_snapshot_definition_st *def )
723 Uint8 buffer[SNAPSHOT_SID_BLOCK_SIZE];
725 int a = xemusnap_write_block_header(def->idstr, SNAPSHOT_SID_BLOCK_VERSION);
727 memset(buffer, 0xFF,
sizeof buffer);
730 return xemusnap_write_sub_block(buffer,
sizeof buffer);