home *** CD-ROM | disk | FTP | other *** search
/ Large Pack of OldSkool DOS MOD Trackers / goattracker_2.68_stereo.zip / src / gsid.cpp < prev    next >
C/C++ Source or Header  |  2009-01-03  |  5KB  |  218 lines

  1. /*
  2.  * GOATTRACKER reSID interface
  3.  */
  4.  
  5. #define GSID_C
  6.  
  7. #include <stdlib.h>
  8. #include "resid/sid.h"
  9. #include "resid-fp/sid.h"
  10.  
  11. extern "C" {
  12.  
  13. #include "gsid.h"
  14. #include "gsound.h"
  15.  
  16. int clockrate;
  17. int samplerate;
  18. unsigned char sidreg[NUMSIDREGS];
  19. unsigned char sidreg2[NUMSIDREGS];
  20.  
  21. unsigned char sidorder[] =
  22.   {0x15,0x16,0x18,0x17,
  23.    0x02,0x03,0x06,0x05,0x00,0x01,0x04,
  24.    0x09,0x0a,0x0d,0x0c,0x07,0x08,0x0b,
  25.    0x10,0x11,0x14,0x13,0x0e,0x0f,0x12};
  26.  
  27. unsigned char altsidorder[] =
  28.   {0x15,0x16,0x18,0x17,
  29.    0x04,0x00,0x01,0x02,0x03,0x05,0x06,
  30.    0x0b,0x07,0x08,0x09,0x0a,0x0c,0x0d,
  31.    0x12,0x0e,0x0f,0x10,0x11,0x13,0x14};
  32.  
  33. SID *sid = 0;
  34. SID *sid2 = 0;
  35. SIDFP *sidfp = 0;
  36. SIDFP *sidfp2 = 0;
  37.  
  38. extern unsigned residdelay;
  39. extern unsigned adparam;
  40.  
  41. void sid_init(int speed, unsigned m, unsigned ntsc, unsigned interpolate, unsigned customclockrate, unsigned usefp)
  42. {
  43.   int c;
  44.  
  45.   if (ntsc) clockrate = NTSCCLOCKRATE;
  46.     else clockrate = PALCLOCKRATE;
  47.  
  48.   if (customclockrate)
  49.     clockrate = customclockrate;
  50.  
  51.   samplerate = speed;
  52.  
  53.   if (!usefp)
  54.   {
  55.     if (!sid) sid = new SID;
  56.     if (!sid2) sid2 = new SID;
  57.     
  58.     if (sidfp) 
  59.     { 
  60.       delete sidfp; 
  61.       sidfp = NULL;
  62.     }
  63.     if (sidfp2)
  64.     { 
  65.       delete sidfp2;
  66.       sidfp = NULL;
  67.     }
  68.   }
  69.   else
  70.   {
  71.     if (!sidfp) sidfp = new SIDFP;
  72.     if (!sidfp2) sidfp2 = new SIDFP;
  73.     
  74.     if (sid)
  75.     {
  76.       delete sid;
  77.       sid = NULL;
  78.     }
  79.     if (sid2)
  80.     {
  81.       delete sid2;
  82.       sid2 = NULL;
  83.     }
  84.   }
  85.  
  86.   switch(interpolate)
  87.   {
  88.     case 0:
  89.     if (sid) sid->set_sampling_parameters(clockrate, SAMPLE_FAST, speed, 20000);
  90.     if (sid2) sid2->set_sampling_parameters(clockrate, SAMPLE_FAST, speed, 20000);
  91.     if (sidfp) sidfp->set_sampling_parameters(clockrate, SAMPLE_FAST, speed, 20000);
  92.     if (sidfp2) sidfp2->set_sampling_parameters(clockrate, SAMPLE_FAST, speed, 20000);
  93.     break;
  94.  
  95.     default:
  96.     if (sid) sid->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed, 20000);
  97.     if (sid2) sid2->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed, 20000);
  98.     if (sidfp) sidfp->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed, 20000);
  99.     if (sidfp2) sidfp2->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed, 20000);
  100.     break;
  101.   }
  102.  
  103.   if (sid) sid->reset();
  104.   if (sid2) sid2->reset();
  105.   if (sidfp) sidfp->reset();
  106.   if (sidfp2) sidfp2->reset();
  107.  
  108.   for (c = 0; c < NUMSIDREGS; c++)
  109.   {
  110.     sidreg[c] = 0x00;
  111.     sidreg2[c] = 0x00;
  112.   }
  113.   if (m == 1)
  114.   {
  115.     if (sid) sid->set_chip_model(MOS8580);
  116.     if (sid2) sid2->set_chip_model(MOS8580);
  117.     if (sidfp) sidfp->set_chip_model(MOS8580FP);
  118.     if (sidfp2) sidfp2->set_chip_model(MOS8580FP);
  119.   }
  120.   else
  121.   {
  122.     if (sid) sid->set_chip_model(MOS6581);
  123.     if (sid2) sid2->set_chip_model(MOS6581);
  124.     if (sidfp) sidfp->set_chip_model(MOS6581FP);
  125.     if (sidfp2) sidfp2->set_chip_model(MOS6581FP);
  126.   }
  127. }
  128.  
  129. unsigned char sid_getorder(unsigned char index)
  130. {
  131.   if (adparam >= 0xf000)
  132.     return altsidorder[index];
  133.   else
  134.     return sidorder[index];
  135. }
  136.  
  137. int sid_fillbuffer(short *lptr, short *rptr, int samples)
  138. {
  139.   int tdelta;
  140.   int tdelta2;
  141.   int result = 0;
  142.   int total = 0;
  143.   int c;
  144.  
  145.   int badline = rand() % NUMSIDREGS;
  146.  
  147.   tdelta = clockrate * samples / samplerate + 4;
  148.  
  149.   for (c = 0; c < NUMSIDREGS; c++)
  150.   {
  151.     unsigned char o = sid_getorder(c);
  152.  
  153.       // Extra delay for loading the waveform (and mt_chngate,x)
  154.       if ((o == 4) || (o == 11) || (o == 18))
  155.       {
  156.         tdelta2 = SIDWAVEDELAY;
  157.       if (sid) result = sid->clock(tdelta2, lptr, samples);
  158.       if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  159.         tdelta2 = SIDWAVEDELAY;
  160.       if (sid2) sid2->clock(tdelta2, rptr, samples);
  161.       if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  162.  
  163.       total += result;
  164.       lptr += result;
  165.       rptr += result;
  166.       samples -= result;
  167.       tdelta -= SIDWAVEDELAY;
  168.     }
  169.  
  170.     // Possible random badline delay once per writing
  171.     if ((badline == c) && (residdelay))
  172.       {
  173.       tdelta2 = residdelay;
  174.       if (sid) result = sid->clock(tdelta2, lptr, samples);
  175.       if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  176.       tdelta2 = residdelay;
  177.       if (sid2) sid2->clock(tdelta2, rptr, samples);
  178.       if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  179.  
  180.       total += result;
  181.       lptr += result;
  182.       rptr += result;
  183.       samples -= result;
  184.       tdelta -= residdelay;
  185.     }
  186.  
  187.     if (sid) sid->write(o, sidreg[o]);
  188.     if (sidfp) sidfp->write(o, sidreg[o]);
  189.     if (sid2) sid2->write(o, sidreg2[o]);
  190.     if (sidfp2) sidfp2->write(o, sidreg2[o]);
  191.  
  192.     tdelta2 = SIDWRITEDELAY;
  193.     if (sid) result = sid->clock(tdelta2, lptr, samples);
  194.     if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  195.     tdelta2 = SIDWRITEDELAY;
  196.     if (sid2) sid2->clock(tdelta2, rptr, samples);
  197.     if (sidfp2) sidfp2->clock(tdelta2, rptr, samples);
  198.  
  199.     total += result;
  200.     lptr += result;
  201.     rptr += result;
  202.     samples -= result;
  203.     tdelta -= SIDWRITEDELAY;
  204.   }
  205.  
  206.   tdelta2 = tdelta;
  207.   if (sid) result = sid->clock(tdelta2, lptr, samples);
  208.   if (sidfp) result = sidfp->clock(tdelta2, lptr, samples);
  209.   tdelta2 = tdelta;
  210.   if (sid2) result = sid2->clock(tdelta2, rptr, samples);
  211.   if (sidfp2) result = sidfp2->clock(tdelta2, rptr, samples);
  212.  
  213.   total += result;
  214.   return total;
  215. }
  216.  
  217. }
  218.