SID.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. SID.cpp - Atmega8 MOS6581 SID Emulator
  3. Copyright (c) 2007 Christoph Haberer, christoph(at)roboterclub-freiburg.de
  4. Arduino Library Conversion by Mario Patino, cybernesto(at)gmail.com
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Lesser General Public
  7. License as published by the Free Software Foundation; either
  8. version 2.1 of the License, or (at your option) any later version.
  9. This library is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. Lesser General Public License for more details.
  13. You should have received a copy of the GNU Lesser General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. */
  17. /************************************************************************
  18. Atmega8 MOS6581 SID Emulator
  19. SID = Sound Interface Device
  20. This program tries to emulate the sound chip SID of the famous
  21. historical C64 Commodore computer.
  22. The SID emulator includes all registers of the original SID, but
  23. some functions may not be implemented yet.
  24. If you want to program the SID registers to generate your own sound,
  25. please refer to the MOS6581 datasheet. The emulator tries to be as
  26. compatible as possible.
  27. In the main program there is an interrupt routine which sets the
  28. ouptut values for the PWM-Output at 62.5kHz. Therefore the high
  29. frequency noise of the PWM should not be audible to normal people.
  30. The output is calculated with a 16kHz sample frequency to save
  31. processing cycles.
  32. The envelope generators are updated every 1ms.
  33. The amplitude value is output as an 8Bit PWM value.
  34. The PWM-Output may be directly connected to an audio amplifier.
  35. ************************************************************************
  36. Hardware
  37. processor: ATMEGA8, ATMEGA168
  38. clock: 16MHz Crystal
  39. PIN15 PB1/OC1A 8Bit PWM sound output
  40. PIN19 PB0 test LED
  41. ***************************************************************************/
  42. #include <avr/interrupt.h>
  43. #include "SID.h"
  44. // attack, decay, release envelope timings
  45. const static uint16_t AttackRate[16]={2,4,16,24,38,58,68,80,100,250,500,800,1000,3000,5000,8000};
  46. const static uint16_t DecayReleaseRate[16]={6,24,48,72,114,168,204,240,300,750,1500,2400,3000,9000,15000,24000};
  47. static uint8_t output;
  48. static Sid_t Sid;
  49. static Oscillator_t osc[OSCILLATORS];
  50. void initialize()
  51. {
  52. // TIMER1 used to generate sound output
  53. // TIMER1: Fast PWM 8-bit
  54. TCCR1A = (1 << WGM10) | (1 << COM1A1) ;
  55. // TIMER1: no prescaling
  56. TCCR1B = (1 << WGM12) | (1 << CS10);
  57. #if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__)
  58. // TIMER2 used to generate sample and ms interrupts
  59. // TIMER2: Normal Mode
  60. TCCR2 = 0;
  61. // TIMER2: clock/8 prescaling
  62. TCCR2 |= (1 << CS21);
  63. // TIMER2: set compare value to generate a 16kHz sample rate
  64. OCR2 = SAMPLERATECOUNT;
  65. // interrupt mask register: enable timer2 OCR2A interrupt
  66. TIMSK = (1 << OCIE2);
  67. // interrupt mask register: enable timer1 overflow
  68. TIMSK |= (1 << TOIE1);
  69. #else
  70. // TIMER2 used to generate sample and ms interrupts
  71. // TIMER2: Normal Mode
  72. TCCR2A = 0 ;
  73. // TIMER2: clock/8 prescaling
  74. TCCR2B = (1 << CS21);
  75. // TIMER2: set compare value to generate a 16kHz sample rate
  76. OCR2A = SAMPLERATECOUNT;
  77. // interrupt mask register: enable timer2 OCR2A interrupt
  78. TIMSK2 = (1 << OCIE2A);
  79. // interrupt mask register: enable timer1 overflow
  80. TIMSK1 = (1 << TOIE1);
  81. #endif
  82. }
  83. static int8_t wave(Voice_t *voice, uint16_t phase)
  84. {
  85. int8_t out;
  86. uint8_t n = phase >> 8;
  87. uint8_t wavetype = voice->ControlReg;
  88. if(wavetype & SAWTOOTH)
  89. {
  90. out = n - 128;
  91. }
  92. if(wavetype & TRIANGLE)
  93. {
  94. if(n&0x80)
  95. out = ((n^0xFF)<<1)-128;
  96. else
  97. out = (n<<1)-128;
  98. }
  99. if(wavetype & RECTANGLE)
  100. {
  101. if(n > (voice->PW >> 4)) // SID has 12Bit pwm, here we use only 8Bit
  102. out = 127;
  103. else
  104. out = -127;
  105. }
  106. return out;
  107. }
  108. static void waveforms()
  109. {
  110. static uint16_t phase[3], sig[3];
  111. static int16_t temp,temp1;
  112. static uint8_t i,j,k;
  113. static uint16_t noise = 0xACE1;
  114. static uint8_t noise8;
  115. static uint16_t tempphase;
  116. // noise generator based on Galois LFSR
  117. noise = (noise >> 1) ^ (-(noise & 1) & 0xB400u);
  118. noise8 = noise>>8;
  119. for(i = 0; i< 3; i++)
  120. {
  121. j = (i == 0 ? 2 : i - 1);
  122. tempphase=phase[i]+osc[i].freq_coefficient; //0.88us
  123. if(Sid.block.voice[i].ControlReg&NOISE)
  124. {
  125. if((tempphase^phase[i])&0x4000) sig[i]=noise8*osc[i].envelope;
  126. }
  127. else
  128. {
  129. if(Sid.block.voice[i].ControlReg&RINGMOD)
  130. {
  131. if(phase[j]&0x8000)
  132. sig[i]=osc[i].envelope*-wave(&Sid.block.voice[i],phase[i]);
  133. else
  134. sig[i]=osc[i].envelope*wave(&Sid.block.voice[i],phase[i]);
  135. }
  136. else
  137. {
  138. if(Sid.block.voice[i].ControlReg&SYNC)
  139. {
  140. if(tempphase < phase[j])
  141. phase[i] = 0;
  142. }
  143. else
  144. sig[i]=osc[i].envelope*wave(&Sid.block.voice[i],phase[i]); //2.07us
  145. }
  146. }
  147. phase[i]=tempphase;
  148. }
  149. // voice filter selection
  150. temp=0; // direct output variable
  151. temp1=0; // filter output variable
  152. if(Sid.block.RES_Filt&FILT1) temp1+=sig[0];
  153. else temp+=sig[0];
  154. if(Sid.block.RES_Filt&FILT2) temp1+=sig[1];
  155. else temp+=sig[1];
  156. if(Sid.block.RES_Filt&FILT3) temp1+=sig[2];
  157. else if(!(Sid.block.Mode_Vol&VOICE3OFF))temp+=sig[2]; // voice 3 with special turn off bit
  158. //filterOutput = IIR2((struct IIR_filter*)&filter04_06, filterInput);
  159. //IIR2(filter04_06, temp1);
  160. k=(temp>>8)+128;
  161. k+=temp1>>10; // no real filter implemeted yet
  162. output = k; // Output to PWM
  163. }
  164. static void envelopes()
  165. {
  166. uint8_t n;
  167. uint8_t controll_regadr[3]={4,11,18};
  168. // if gate is ONE then the attack,decay,sustain cycle begins
  169. // if gate switches to zero the sound decays
  170. for(n=0;n<OSCILLATORS;n++)
  171. {
  172. if(Sid.sidregister[controll_regadr[n]]&GATE) // if gate set then attack,decay,sustain
  173. {
  174. if(osc[n].attackdecay_flag)
  175. { // if attack cycle
  176. osc[n].amp+=osc[n].m_attack;
  177. if(osc[n].amp>MAXLEVEL)
  178. {
  179. osc[n].amp=MAXLEVEL;
  180. osc[n].attackdecay_flag=false; // if level reached, then switch to decay
  181. }
  182. }
  183. else // decay cycle
  184. {
  185. if(osc[n].amp>osc[n].level_sustain)
  186. {
  187. osc[n].amp-=osc[n].m_decay;
  188. if(osc[n].amp<osc[n].level_sustain) osc[n].amp=osc[n].level_sustain;
  189. }
  190. }
  191. }
  192. else // if gate flag is not set then release
  193. {
  194. osc[n].attackdecay_flag=true; // at next attack/decay cycle start wiht attack
  195. if(osc[n].amp>0)
  196. {
  197. osc[n].amp-=osc[n].m_release;
  198. if(osc[n].amp<0) osc[n].amp=0;
  199. }
  200. }
  201. osc[n].envelope=osc[n].amp>>8;
  202. }
  203. }
  204. /************************************************************************
  205. interrupt routine timer 1 overflow
  206. - set PWM output
  207. ************************************************************************/
  208. ISR(TIMER1_OVF_vect)
  209. {
  210. OCR1A = output; // Output to PWM
  211. }
  212. /************************************************************************
  213. interrupt routine timer 2 16kHz
  214. - calculate waverform phases
  215. - calculate waveforms
  216. - calculate attack decay release (1kHz)
  217. ************************************************************************/
  218. #if defined(__AVR_ATmega8__)|| defined(__AVR_ATmega128__)
  219. ISR(TIMER2_COMP_vect)
  220. {
  221. static uint8_t mscounter = 0;
  222. OCR2 += SAMPLERATECOUNT; // Output to PWM
  223. waveforms(); //~22us
  224. if(mscounter++ >= MSCOUNT)
  225. {
  226. envelopes(); //~16us
  227. mscounter = 0;
  228. }
  229. }
  230. #else
  231. ISR(TIMER2_COMPA_vect)
  232. {
  233. static uint8_t mscounter = 0;
  234. OCR2A += SAMPLERATECOUNT; // Output to PWM
  235. waveforms(); //~36us
  236. if(mscounter++ >= MSCOUNT)
  237. {
  238. envelopes(); //~16us
  239. mscounter = 0;
  240. }
  241. }
  242. #endif
  243. // Constructor /////////////////////////////////////////////////////////////////
  244. // Function that handles the creation and setup of instances
  245. void SID::begin()
  246. {
  247. pinMode(9, OUTPUT);
  248. initialize();
  249. //initialize SID-registers
  250. Sid.sidregister[6]=0xF0;
  251. Sid.sidregister[13]=0xF0;
  252. Sid.sidregister[20]=0xF0;
  253. // set all amplitudes to zero
  254. for(int n=0;n<OSCILLATORS;n++) {
  255. osc[n].attackdecay_flag=true;
  256. setenvelope(&Sid.block.voice[n]);
  257. osc[n].amp=0;
  258. }
  259. }
  260. // Public Methods //////////////////////////////////////////////////////////////
  261. // Functions available in Wiring sketches, this library, and other libraries
  262. /************************************************************************
  263. uint8_t set_sidregister(uint8_t regnum, uint8_t value)
  264. The registers of the virtual SID are set by this routine.
  265. For some registers it is necessary to transform the SID-register
  266. values to some internal settings of the emulator.
  267. To select this registers and to start the calculation, the switch/
  268. case statement is used.
  269. For instance: If setting the SID envelope register, new attach, decay
  270. sustain times are calculated.
  271. If an invalid register is requested the returned value will be 0.
  272. 4.2007 ch
  273. ************************************************************************/
  274. uint8_t SID::set_register(uint8_t regnum, uint8_t value)
  275. {
  276. if(regnum>NUMREGISTERS-1)
  277. return 0;
  278. Sid.sidregister[regnum]=value;
  279. switch(regnum)
  280. {
  281. //voice1
  282. case 1:
  283. osc[0].freq_coefficient=((uint16_t)Sid.sidregister[0]+((uint16_t)Sid.sidregister[1]<<8))>>2;
  284. break;
  285. case 5: setenvelope(&Sid.block.voice[0]);break;
  286. case 6: setenvelope(&Sid.block.voice[0]);break;
  287. //voice2
  288. case 8:
  289. osc[1].freq_coefficient=((uint16_t)Sid.sidregister[7]+((uint16_t)Sid.sidregister[8]<<8))>>2;
  290. break;
  291. case 12: setenvelope(&Sid.block.voice[1]);break;
  292. case 13: setenvelope(&Sid.block.voice[1]);break;
  293. //voice3
  294. case 15:
  295. osc[2].freq_coefficient=((uint16_t)Sid.sidregister[14]+((uint16_t)Sid.sidregister[15]<<8))>>2;
  296. break;
  297. case 19: setenvelope(&Sid.block.voice[2]);break;
  298. case 20: setenvelope(&Sid.block.voice[2]);break;
  299. }
  300. return 1;
  301. }
  302. /************************************************************************
  303. uint8_t get_sidregister(uint8_t regnum)
  304. The registers of the virtual SID are read by this routine.
  305. If an invalid register is requested it returns zero.
  306. ************************************************************************/
  307. uint8_t SID::get_register(uint8_t regnum)
  308. {
  309. if(regnum>NUMREGISTERS-1)
  310. return 0;
  311. return Sid.sidregister[regnum];
  312. }
  313. // Private Methods /////////////////////////////////////////////////////////////
  314. // Functions only available to other functions in this library
  315. uint8_t SID::get_wavenum(Voice_t *voice)
  316. {
  317. uint8_t n;
  318. if(voice==&Sid.block.voice[0]) n=0;
  319. if(voice==&Sid.block.voice[1]) n=1;
  320. if(voice==&Sid.block.voice[2]) n=2;
  321. return n;
  322. }
  323. void SID::setfreq(Voice_t *voice,uint16_t freq)
  324. {
  325. uint32_t templong;
  326. uint8_t n;
  327. n=get_wavenum(voice);
  328. templong=freq;
  329. osc[n].freq_coefficient=templong*4000/SAMPLEFREQ;
  330. }
  331. void SID::setenvelope(Voice_t *voice)
  332. {
  333. uint8_t n;
  334. n=get_wavenum(voice);
  335. osc[n].attackdecay_flag=true;
  336. osc[n].level_sustain=(voice->SustainRelease>>4)*SUSTAINFACTOR;
  337. osc[n].m_attack=MAXLEVEL/AttackRate[voice->AttackDecay>>4];
  338. osc[n].m_decay=(MAXLEVEL-osc[n].level_sustain*SUSTAINFACTOR)/DecayReleaseRate[voice->AttackDecay&0x0F];
  339. osc[n].m_release=(osc[n].level_sustain)/DecayReleaseRate[voice->SustainRelease&0x0F];
  340. }