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);