Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- uint16_t *vu; // 3ad0
- uint8_t playOnce; // 3b11
- uint8_t playing; // 3b10
- uint16_t *rowPtrs; // 415a
- uint8_t stereo; // 41be
- uint16_t *instPtrs; // 41c0
- uint8_t *volTable; // 41de
- uint16_t *freqTable; // 4260
- uint16_t timer; // 4346
- uint8_t songLen; // 4348
- uint8_t curRow; // 434a
- uint8_t curPattern; // 434c
- uint16_t rowOffset; // 434e
- uint16_t tempo; // 4352
- uint16_t vol; // 4354
- uint8_t numInst; // 4356
- uint8_t *chanInst; // 4358
- uint8_t *chanVib; // 4366
- uint8_t *chanFreq; // 4374
- uint16_t *chanVol; // 4382
- uint8_t chanAddr; // 439e
- uint8_t channel; // 43a0
- uint8_t note; // 43a2
- uint8_t oscAptr; // 43a4
- uint8_t oscAsiz; // 43a5
- uint8_t oscActl; // 43a6
- uint8_t oscBptr; // 43a8
- uint8_t oscBsiz; // 43a9
- uint8_t oscBctl; // 43aa
- uint16_t sampFreq; // 43ac
- uint16_t *instVol; // 43b0
- uint16_t *stereoTable; // 43d0
- uint16_t *shiftTable; // 43f0
- uint8_t *instdef; // 4410
- uint8_t soundCtl; // c03c
- uint8_t soundData; // c03d
- uint8_t soundAdrL; // c03e
- uint8_t soundAdrH; // c03f
- uint8_t *music; // a:0400
- uint8_t *effects1; // address at 3cd4 + 1
- uint8_t *effects2; // address at 3cd9 + 1
- void soundInterrupt() {
- while (soundCtl & 0x80); // wait for DOC to finish
- soundCtl &= 0x9f; // DOC mode, no autoinc
- soundAdrL = 0xe0; // oscillator interrupt
- soundData &= 0x7f; // clear interrupt flag
- uint8_t osc = (soundData & 0x3e) >> 1; // which osc halted
- if (osc != 0) { // normal channel, not the timer
- soundAdrL = 0xa0 + osc; // osc control;
- if (soundData & 8) { // does this osc have interrupts enabled?
- soundData &= 0xfe; // clear halt bit, restart the oscillator
- }
- return;
- }
- if (playing == 0)
- return;
- channel = 0;
- timer++;
- // time to play new notes?
- if (timer != tempo) { // no. so do effects
- for (channel = 0; channel < 14; channel++) { // 406c
- if (chanVol[channel] >= 3)
- chanVol[channel] -= 3;
- else
- chanVol[channel] = 0;
- if (chanVib[channel] == 0) // no vibrato
- continue;
- uint8_t tmp;
- switch (timer % 6) { // apply vibrato
- case 1: case 4:
- chanFreq[channel] += chanVib[channel] >> 4;
- break;
- case 2: case 5:
- chanFreq[channel] += chanVib[channel] & 0xf;
- break;
- default: // 0 or 3
- tmp = chanVib[channel] & 0xf;
- tmp += chanVib[channel] >> 4;
- chanFreq[channel] -= tmp;
- break;
- }
- sampFreq = freqTable[chanFreq[channel]] >> shiftTable[channel];
- chanAddr = (channel + 1) * 2;
- while (soundCtl & 0x80); // wait for DOC
- soundCtl = (soundCtl | 0x20) & 0xbf; // DOC + autoinc
- soundAdrL = chanAddr; // frequency low
- soundData = sampFreq & 0xff;
- soundData = sampFreq & 0xff; // adjust freq for channel pair
- soundAdrL = chanAddr + 0x20; // frequency hi
- soundData = sampFreq >> 8;
- soundData = sampFreq >> 8; // freq for channel pair
- }
- return;
- }
- // play next row
- timer = 0;
- for (channel = 0; channel < 14; channel++) {
- note = music[600 + rowOffset];
- if (note >= 0x80) {
- if (note == 0x81) {
- curRow = 0x3f;
- } else if (note == 0x80) {
- chanVol[channel] = 0;
- // the code here does nothing.. it looks like it intended to halt
- // the channel and its pair, but it's been disabled.
- }
- } else {
- uint8_t inst = effects1[rowOffset] & 0xf0;
- if (inst == 0)
- inst = chanInst[channel];
- chanInst[channel] = inst;
- vol = instVol[(inst >> 4) - 1] / 2;
- uint8_t fx = effects1[rowOffset] & 0xf;
- if (fx == 0) {
- chanVib[channel] = effects2[rowOffset];
- chanFreq[channel] = note;
- } else {
- chanVib[channel] = 0;
- if (fx == 3 || fx == 6 || fx == 5) {
- if (fx == 3) {
- vol = effects2[rowOffset] / 2;
- } else if (fx == 6) {
- vol -= effects2[rowOffset] / 2;
- if (vol < 0)
- vol = 0;
- } else if (fx == 5) {
- vol += effects2[rowOffset] / 2;
- if (vol > 0x7f)
- vol = 0x7f;
- }
- if (note == 0) {
- chanAddr = (channel + 1) * 2;
- while (soundCtl & 0x80); // wait for doc
- soundCtl = (soundCtl | 0x20) & 0xbf; // doc + autoinc
- soundAdrL = chanAddr + 0x40; // channel volume
- soundData = vol;
- soundData = vol; // set oscillator pair's volume
- }
- } else if (fx == 0xf) {
- tempo = effects2[rowOffset] & 0xf;
- }
- }
- chanVol[channel] = vol;
- if (note) {
- chanAddr = (channel + 1) * 2;
- soundCtl &= 0x9f; // DOC + no autoinc
- soundAdrL = chanAddr + 0xa0; // osc ctl
- soundData = (soundData & 0xf7) | 1; // halt without interrupt
- soundAdrL = chanAddr + 1 + 0xa0; // osc ctl for pair
- soundData = (soundData & 0x7f) | 1; // halt without interrupt
- uint8_t inst = (chanInst[channel] >> 4) - 1;
- if (inst >= numInst) {
- rowOffset++;
- continue;
- }
- uint16_t x = instPtrs[inst];
- while (instdef[x] < note) {
- x += 6;
- }
- // oscillator A
- oscAptr = instdef[x + 1];
- oscAsiz = instdef[x + 2];
- oscActl = instdef[x + 3];
- if (stereo) {
- oscActl &= 0xf;
- if (stereoTable[channel])
- oscActl |= 0x10;
- }
- while (instdef[x] != 0x7f) {
- x += 6;
- }
- x += 6; // skip final instdef
- while (instdef[x] < note) {
- x += 6;
- }
- // oscillator B
- oscBptr = instdef[x + 1];
- oscBsiz = instdef[x + 2];
- oscBctl = instdef[x + 3];
- if (stereo) {
- oscBctl &= 0xf;
- if (stereoTable[channel])
- oscBctl |= 0x10;
- }
- sampFreq = freqTable[note] >> shiftTable[channel];
- vu[channel] = vol >> 3;
- while (soundCtl & 0x80); // wait for DOC
- soundCtl = (soundCtl | 0x20) & 0xbf; // DOC + autoinc
- soundAdrL = chanAddr; // freq lo
- soundData = sampFreq & 0xff;
- soundData = sampFreq & 0xff; // pair
- soundAdrL = chanAddr + 0x20; // freq hi
- soundData = sampFreq >> 8;
- soundData = sampFreq >> 8; // pair
- soundAdrL = chanAddr + 0x40; // volume
- soundData = volTable[vol];
- soundData = volTable[vol]; // pair
- soundAdrL = chanAddr + 0x80; // wavetable ptr
- soundData = oscAptr;
- soundData = oscBptr; // pair
- soundAdrL = chanAddr + 0xc0; // wavetable size
- soundData = oscAsiz;
- soundData = oscBsiz; // pair
- soundAdrL = chanAddr + 0xa0; // osc ctl
- soundData = oscActl;
- soundData = oscBctl; // pair
- }
- rowOffset++;
- }
- }
- curRow++;
- if (curRow == 0x40) { // end of pattern?
- curRow = 0;
- curPattern++;
- if (curPattern == songLen) { // end of song?
- if (playOnce) {
- playing = 0;
- } else {
- // reset song
- }
- } else {
- rowOffset = rowPtrs[music[0x1d8 + curPattern]];
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement