Advertisement
mrkite

soundinterrupt.c

Dec 13th, 2016
395
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.22 KB | None | 0 0
  1. uint16_t *vu;  // 3ad0
  2. uint8_t playOnce;  // 3b11
  3. uint8_t playing;  // 3b10
  4. uint16_t *rowPtrs;  // 415a
  5. uint8_t stereo;  // 41be
  6. uint16_t *instPtrs;  // 41c0
  7. uint8_t *volTable;  // 41de
  8. uint16_t *freqTable;  // 4260
  9. uint16_t timer;  // 4346
  10. uint8_t songLen;  // 4348
  11. uint8_t curRow;  // 434a
  12. uint8_t curPattern;  // 434c
  13. uint16_t rowOffset;  // 434e
  14. uint16_t tempo;  // 4352
  15. uint16_t vol;  // 4354
  16. uint8_t numInst; // 4356
  17. uint8_t *chanInst;  // 4358
  18. uint8_t *chanVib;  // 4366
  19. uint8_t *chanFreq;  // 4374
  20. uint16_t *chanVol;  // 4382
  21. uint8_t chanAddr;  // 439e
  22. uint8_t channel;  // 43a0
  23. uint8_t note;  // 43a2
  24. uint8_t oscAptr;  // 43a4
  25. uint8_t oscAsiz;  // 43a5
  26. uint8_t oscActl;  // 43a6
  27. uint8_t oscBptr;  // 43a8
  28. uint8_t oscBsiz;  // 43a9
  29. uint8_t oscBctl;  // 43aa
  30. uint16_t sampFreq;  // 43ac
  31. uint16_t *instVol;  // 43b0
  32. uint16_t *stereoTable;  // 43d0
  33. uint16_t *shiftTable;  // 43f0
  34. uint8_t *instdef;  // 4410
  35. uint8_t soundCtl;  // c03c
  36. uint8_t soundData;  // c03d
  37. uint8_t soundAdrL;  // c03e
  38. uint8_t soundAdrH;  // c03f
  39. uint8_t *music;  // a:0400
  40. uint8_t *effects1;  // address at 3cd4 + 1
  41. uint8_t *effects2;  // address at 3cd9 + 1
  42.  
  43. void soundInterrupt() {
  44.   while (soundCtl & 0x80);  // wait for DOC to finish
  45.   soundCtl &= 0x9f;  // DOC mode, no autoinc
  46.   soundAdrL = 0xe0;  // oscillator interrupt
  47.   soundData &= 0x7f;  // clear interrupt flag
  48.  
  49.   uint8_t osc = (soundData & 0x3e) >> 1;  // which osc halted
  50.   if (osc != 0) {  // normal channel, not the timer
  51.     soundAdrL = 0xa0 + osc;  // osc control;
  52.     if (soundData & 8) {  // does this osc have interrupts enabled?
  53.       soundData &= 0xfe;  // clear halt bit, restart the oscillator
  54.     }
  55.     return;
  56.   }
  57.   if (playing == 0)
  58.     return;
  59.   channel = 0;
  60.   timer++;
  61.   // time to play new notes?
  62.   if (timer != tempo) { // no.  so do effects
  63.     for (channel = 0; channel < 14; channel++) {  // 406c
  64.       if (chanVol[channel] >= 3)
  65.         chanVol[channel] -= 3;
  66.       else
  67.         chanVol[channel] = 0;
  68.       if (chanVib[channel] == 0)  // no vibrato
  69.         continue;
  70.       uint8_t tmp;
  71.       switch (timer % 6) {  // apply vibrato
  72.         case 1: case 4:
  73.           chanFreq[channel] += chanVib[channel] >> 4;
  74.           break;
  75.         case 2: case 5:
  76.           chanFreq[channel] += chanVib[channel] & 0xf;
  77.           break;
  78.         default:  // 0 or 3
  79.           tmp = chanVib[channel] & 0xf;
  80.           tmp += chanVib[channel] >> 4;
  81.           chanFreq[channel] -= tmp;
  82.           break;
  83.       }
  84.       sampFreq = freqTable[chanFreq[channel]] >> shiftTable[channel];
  85.       chanAddr = (channel + 1) * 2;
  86.       while (soundCtl & 0x80);  // wait for DOC
  87.       soundCtl = (soundCtl | 0x20) & 0xbf;  // DOC + autoinc
  88.       soundAdrL = chanAddr;  // frequency low
  89.       soundData = sampFreq & 0xff;
  90.       soundData = sampFreq & 0xff;  // adjust freq for channel pair
  91.       soundAdrL = chanAddr + 0x20;  // frequency hi
  92.       soundData = sampFreq >> 8;
  93.       soundData = sampFreq >> 8;  // freq for channel pair
  94.     }
  95.     return;
  96.   }
  97.  
  98.   // play next row
  99.  
  100.   timer = 0;
  101.   for (channel = 0; channel < 14; channel++) {
  102.     note = music[600 + rowOffset];
  103.     if (note >= 0x80) {
  104.       if (note == 0x81) {
  105.         curRow = 0x3f;
  106.       } else if (note == 0x80) {
  107.         chanVol[channel] = 0;
  108.         // the code here does nothing.. it looks like it intended to halt
  109.         // the channel and its pair, but it's been disabled.
  110.       }
  111.     } else {
  112.       uint8_t inst = effects1[rowOffset] & 0xf0;
  113.       if (inst == 0)
  114.         inst = chanInst[channel];
  115.       chanInst[channel] = inst;
  116.       vol = instVol[(inst >> 4) - 1] / 2;
  117.       uint8_t fx = effects1[rowOffset] & 0xf;
  118.       if (fx == 0) {
  119.         chanVib[channel] = effects2[rowOffset];
  120.         chanFreq[channel] = note;
  121.       } else {
  122.         chanVib[channel] = 0;
  123.         if (fx == 3 || fx == 6 || fx == 5) {
  124.           if (fx == 3) {
  125.             vol = effects2[rowOffset] / 2;
  126.           } else if (fx == 6) {
  127.             vol -= effects2[rowOffset] / 2;
  128.             if (vol < 0)
  129.               vol = 0;
  130.           } else if (fx == 5) {
  131.             vol += effects2[rowOffset] / 2;
  132.             if (vol > 0x7f)
  133.               vol = 0x7f;
  134.           }
  135.           if (note == 0) {
  136.             chanAddr = (channel + 1) * 2;
  137.             while (soundCtl & 0x80);  // wait for doc
  138.             soundCtl = (soundCtl | 0x20) & 0xbf;  // doc + autoinc
  139.             soundAdrL = chanAddr + 0x40;  // channel volume
  140.             soundData = vol;
  141.             soundData = vol;  // set oscillator pair's volume
  142.           }
  143.         } else if (fx == 0xf) {
  144.           tempo = effects2[rowOffset] & 0xf;
  145.         }
  146.       }
  147.       chanVol[channel] = vol;
  148.       if (note) {
  149.         chanAddr = (channel + 1) * 2;
  150.         soundCtl &= 0x9f;  // DOC + no autoinc
  151.         soundAdrL = chanAddr + 0xa0;  // osc ctl
  152.         soundData = (soundData & 0xf7) | 1;  // halt without interrupt
  153.         soundAdrL = chanAddr + 1 + 0xa0;  // osc ctl for pair
  154.         soundData = (soundData & 0x7f) | 1;  // halt without interrupt
  155.         uint8_t inst = (chanInst[channel] >> 4) - 1;
  156.         if (inst >= numInst) {
  157.           rowOffset++;
  158.           continue;
  159.         }
  160.         uint16_t x = instPtrs[inst];
  161.         while (instdef[x] < note) {
  162.           x += 6;
  163.         }
  164.         // oscillator A
  165.         oscAptr = instdef[x + 1];
  166.         oscAsiz = instdef[x + 2];
  167.         oscActl = instdef[x + 3];
  168.         if (stereo) {
  169.           oscActl &= 0xf;
  170.           if (stereoTable[channel])
  171.             oscActl |= 0x10;
  172.         }
  173.         while (instdef[x] != 0x7f) {
  174.           x += 6;
  175.         }
  176.         x += 6;  // skip final instdef
  177.         while (instdef[x] < note) {
  178.           x += 6;
  179.         }
  180.         // oscillator B
  181.         oscBptr = instdef[x + 1];
  182.         oscBsiz = instdef[x + 2];
  183.         oscBctl = instdef[x + 3];
  184.         if (stereo) {
  185.           oscBctl &= 0xf;
  186.           if (stereoTable[channel])
  187.             oscBctl |= 0x10;
  188.         }
  189.         sampFreq = freqTable[note] >> shiftTable[channel];
  190.         vu[channel] = vol >> 3;
  191.         while (soundCtl & 0x80);  // wait for DOC
  192.         soundCtl = (soundCtl | 0x20) & 0xbf;  // DOC + autoinc
  193.         soundAdrL = chanAddr;  // freq lo
  194.         soundData = sampFreq & 0xff;
  195.         soundData = sampFreq & 0xff;  // pair
  196.         soundAdrL = chanAddr + 0x20;  // freq hi
  197.         soundData = sampFreq >> 8;
  198.         soundData = sampFreq >> 8;  // pair
  199.         soundAdrL = chanAddr + 0x40;  // volume
  200.         soundData = volTable[vol];
  201.         soundData = volTable[vol];  // pair
  202.         soundAdrL = chanAddr + 0x80;  // wavetable ptr
  203.         soundData = oscAptr;
  204.         soundData = oscBptr;  // pair
  205.         soundAdrL = chanAddr + 0xc0;  // wavetable size
  206.         soundData = oscAsiz;
  207.         soundData = oscBsiz;  // pair
  208.         soundAdrL = chanAddr + 0xa0;  // osc ctl
  209.         soundData = oscActl;
  210.         soundData = oscBctl; // pair
  211.       }
  212.       rowOffset++;
  213.     }
  214.   }
  215.   curRow++;
  216.   if (curRow == 0x40) {  // end of pattern?
  217.     curRow = 0;
  218.     curPattern++;
  219.     if (curPattern == songLen) {  // end of song?
  220.       if (playOnce) {
  221.         playing = 0;
  222.       } else {
  223.         // reset song
  224.       }
  225.     } else {
  226.       rowOffset = rowPtrs[music[0x1d8 + curPattern]];
  227.     }
  228.   }
  229. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement