diff --git a/board-package-source/libraries/ATMlib/src/ATMlib.cpp b/board-package-source/libraries/ATMlib/src/ATMlib.cpp index e924b8d..bca38fd 100644 --- a/board-package-source/libraries/ATMlib/src/ATMlib.cpp +++ b/board-package-source/libraries/ATMlib/src/ATMlib.cpp @@ -1,9 +1,192 @@ #include "ATMlib.h" -#ifndef AB_ALTERNATE_WIRING - ATMLIB_CONSTRUCT_ISR(OCR4A) +uint16_t __attribute__((used)) cia, __attribute__((used)) cia_count; +#ifdef __AVR_ARCH__ +ISR(TIMER4_OVF_vect, ISR_NAKED) { + asm volatile( + "push r18 \n" + "lds r18, half \n" // half = !half; + "sbrc r18, 0 \n" // if (half) return; + "rjmp 2f \n" + "ldi r18, 0xFF \n" + "1: \n" + "sts half, r18 \n" + "pop r18 \n" + "reti \n" + "2: \n" + "push r0 \n" + "push r1 \n" + "push r2 \n" + "in r2, __SREG__ \n" + "push r30 \n" + "push r31 \n" + "ldi r30, lo8(osc) \n" + "ldi r31, hi8(osc) \n" + + "ldi r18, 1 \n" + "ldd r0, Z+3*%[mul]+%[fre] \n" // uint16_t freq = osc[3].freq; //noise frequency + "ldd r1, Z+3*%[mul]+%[fre]+1 \n" + "add r0, r0 \n" // freq <<= 1; + "adc r1, r1 \n" + "sbrc r1, 7 \n" // if (freq & 0x8000) freq ^= 1; + "eor r0, r18 \n" + "sbrc r1, 6 \n" // if (freq & 0x4000) freq ^= 1; + "eor r0, r18 \n" + "std Z+3*%[mul]+%[fre], r0 \n" // osc[3].freq = freq; + "std Z+3*%[mul]+%[fre]+1, r1 \n" + + "ldd r18, Z+3*%[mul]+%[vol] \n" // int8_t vol = osc[3].vol; + "sbrc r1, 7 \n" // if (freq & 0x8000) vol = -vol; + "neg r18 \n" + "mov r1, r18 \n" + + "ldd r0, Z+0*%[mul]+%[fre] \n" // osc[0].phase += osc[0].freq; // update pulse phase + "ldd r18, Z+0*%[mul]+%[pha] \n" + "add r18, r0 \n" + "std Z+0*%[mul]+%[pha], r18 \n" + "ldd r0, Z+0*%[mul]+%[fre]+1 \n" + "ldd r18, Z+0*%[mul]+%[pha]+1 \n" + "adc r18, r0 \n" + "std Z+0*%[mul]+%[pha]+1, r18 \n" + + "ldd r0, Z+0*%[mul]+%[vol] \n" // int8_t vol0 = osc[0].vol; + "cpi r18, 192 \n" // if (uint8_t(osc[0].phase >> 8) >= 192) vol0 = -vol0; + "brcs 3f \n" + "neg r0 \n" + "add r1, r0 \n" // int8_t vol += vol0; + "3: \n" + + "ldd r18, Z+1*%[mul]+%[fre] \n" // osc[1].phase += osc[1].freq; // update square phase + "ldd r0, Z+1*%[mul]+%[pha] \n" + "add r0, r18 \n" + "std Z+1*%[mul]+%[pha], r0 \n" + "ldd r18, Z+1*%[mul]+%[fre]+1 \n" + "ldd r0, Z+1*%[mul]+%[pha]+1 \n" + "adc r0, r18 \n" + "std Z+1*%[mul]+%[pha]+1, r0 \n" + + "ldd r18, Z+1*%[mul]+%[vol] \n" // int8_t vol1 = osc[1].vol; + "sbrc r0, 7 \n" // if (osc[1].phase & 0x8000) vol1 = -vol1; + "neg r18 \n" + "add r1, r18 \n" // vol += vol1; + + "ldd r18, Z+2*%[mul]+%[fre] \n" // osc[2].phase += osc[2].freq;// update triangle phase + "ldd r0, Z+2*%[mul]+%[pha] \n" + "add r0, r18 \n" + "std Z+2*%[mul]+%[pha], r0 \n" + "ldd r0, Z+2*%[mul]+%[fre]+1 \n" + "ldd r18, Z+2*%[mul]+%[pha]+1 \n" + "adc r18, r0 \n" + "std Z+2*%[mul]+%[pha]+1, r18 \n" + // int8_t phase2 = osc[2].phase >> 8; + "ldd r30, Z+2*%[mul]+%[vol] \n" // int8_t vol2 = osc[2].vol; + "lds r31, pcm \n" // int8_t tmp = pcm + vol; + "add r31, r1 \n" + "sbrc r18, 7 \n" // if (phase2 < 0) phase2 = ~phase2; + "com r18 \n" + "lsl r18 \n" // phase2 <<= 1; + "subi r18, 128 \n" // phase2 -= 128; + "muls r18, r30 \n" // vol = ((phase2 * vol2) << 1) >> 8 + tmp; + "lsl r1 \n" + "add r1, r31 \n" + + "sts %[reg], r1 \n" // reg = vol; + #ifdef AB_ALTERNATE_WIRING + "sts %[reg2], r1 \n" // reg2 = vol; + #endif + "lds r31, cia_count+1 \n" // if (--cia_count) return; + "lds r30, cia_count \n" + "sbiw r30, 1 \n" + "brne 4f \n" + "lds r31, cia+1 \n" // cia_count = cia; + "lds r30, cia \n" + "4: \n" + "sts cia_count+1, r31 \n" + "sts cia_count, r30 \n" + "brne 5f \n" + + "sei \n" // sei(); + "push r19 \n" + "push r20 \n" + "push r21 \n" + "push r22 \n" + "push r23 \n" + "push r24 \n" + "push r25 \n" + "push r26 \n" + "push r27 \n" + + "clr r1 \n" + "call ATM_playroutine \n" // ATM_playroutine(); + + "pop r27 \n" // } + "pop r26 \n" + "pop r25 \n" + "pop r24 \n" + "pop r23 \n" + "pop r22 \n" + "pop r21 \n" + "pop r20 \n" + "pop r19 \n" + "5: \n" + "pop r31 \n" + "pop r30 \n" + "out __SREG__, r2 \n" + "pop r2 \n" + "pop r1 \n" + "pop r0 \n" + "ldi r18, 0x00 \n" + "rjmp 1b \n" + : + : [reg] "M" _SFR_MEM_ADDR(OCR4A), + #ifdef AB_ALTERNATE_WIRING + [reg2] "M" _SFR_MEM_ADDR(OCR4D), + #endif + [mul] "M" (sizeof(Oscillator)), + [pha] "M" (offsetof(Oscillator, phase)), + [fre] "M" (offsetof(Oscillator, freq)), + [vol] "M" (offsetof(Oscillator, vol)) + ); +} #else - ATMLIB_CONSTRUCT_ISR(OCR4A,OCR4D) +ISR(TIMER4_OVF_vect) +{ + half = !half; + if (half) return; + + osc[2].phase += osc[2].freq; // update triangle phase + int8_t phase2 = osc[2].phase >> 8; + if (phase2 < 0) phase2 = ~phase2; + phase2 <<= 1; + phase2 -= 128; + int8_t vol = ((phase2 * int8_t(osc[2].vol)) << 1) >> 8; + + osc[0].phase += osc[0].freq; // update pulse phase + int8_t vol0 = osc[0].vol; + if (osc[0].phase >= 0xC000) vol0 = -vol0; + vol += vol0; + + osc[1].phase += osc[1].freq; // update square phase + int8_t vol1 = osc[1].vol; + if (osc[1].phase & 0x8000) vol1 = -vol1; + vol += vol1; + + uint16_t freq = osc[3].freq; //noise frequency + freq <<= 1; + if (freq & 0x8000) freq ^= 1; + if (freq & 0x4000) freq ^= 1; + osc[3].freq = freq; + int8_t vol3 = osc[3].vol; + if (freq & 0x8000) vol3 = -vol3; + vol += vol3; + + OCR4A = vol + pcm; + if (--cia_count) return; + + cia_count = cia; + sei(); + ATM_playroutine(); +} #endif byte trackCount; @@ -131,7 +314,7 @@ void ATMsynth::play(const byte *song) { #ifdef AB_ALTERNATE_WIRING TCCR4C = 0b01000101; OCR4D = 0x80; -#endif +#endif // Load a melody stream and start grinding samples // Read track count @@ -162,11 +345,11 @@ void ATMsynth::playPause() { // Toggle mute on/off on a channel, so it can be used for sound effects // So you have to call it before and after the sound effect void ATMsynth::muteChannel(byte ch) { - ChannelActiveMute += (1 << 0 ); + ChannelActiveMute += (1 << ch ); } void ATMsynth::unMuteChannel(byte ch) { - ChannelActiveMute &= (~(1 << 0 )); + ChannelActiveMute &= (~(1 << ch )); } @@ -406,7 +589,7 @@ void ATM_playroutine() { } } // if all channels are inactive, stop playing or check for repeat - + if (!(ChannelActiveMute & 0xF0)) { byte repeatSong = 0; diff --git a/board-package-source/libraries/ATMlib/src/ATMlib.h b/board-package-source/libraries/ATMlib/src/ATMlib.h index e72bd32..26acc74 100644 --- a/board-package-source/libraries/ATMlib/src/ATMlib.h +++ b/board-package-source/libraries/ATMlib/src/ATMlib.h @@ -51,303 +51,5 @@ extern osc_t osc[4]; uint16_t read_vle(const byte **pp); static inline const byte *getTrackPointer(byte track); - - extern void ATM_playroutine() asm("ATM_playroutine"); - -#ifndef AB_ALTERNATE_WIRING -#define ATMLIB_CONSTRUCT_ISR(TARGET_REGISTER) \ -uint16_t __attribute__((used)) cia, __attribute__((used)) cia_count; \ -ISR(TIMER4_OVF_vect, ISR_NAKED) { \ - asm volatile( \ - "push r2 " "\n\t" \ - "in r2, __SREG__ " "\n\t" \ - "push r18 " "\n\t" \ - "lds r18, half " "\n\t" \ - "com r18 " "\n\t" \ - "sts half, r18 " "\n\t" \ - "breq 1f " "\n\t" \ - "rjmp 3f " "\n\t" \ - "1: " "\n\t" \ - "push r27 " "\n\t" \ - "push r26 " "\n\t" \ - "push r0 " "\n\t" \ - "push r1 " "\n\t" \ - \ - "lds r18, osc+2*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+2*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+2*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+2*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+2*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+2*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "mov r27, r1 " "\n\t" \ - "sbrc r27, 7 " "\n\t" \ - "com r27 " "\n\t" \ - "lsl r27 " "\n\t" \ - "lds r26, osc+2*%[mul]+%[vol] " "\n\t" \ - "subi r27, 128 " "\n\t" \ - "muls r27, r26 " "\n\t" \ - "lsl r1 " "\n\t" \ - "mov r26, r1 " "\n\t" \ - \ - "lds r18, osc+0*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+0*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+0*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+0*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+0*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+0*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "mov r18, r1 " "\n\t" \ - "lsl r18 " "\n\t" \ - "and r18, r1 " "\n\t" \ - "lds r27, osc+0*%[mul]+%[vol] " "\n\t" \ - "sbrc r18, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "lds r18, osc+1*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+1*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+1*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+1*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+1*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+1*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "lds r27, osc+1*%[mul]+%[vol] " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "ldi r27, 1 " "\n\t" \ - "lds r0, osc+3*%[mul]+%[fre] " "\n\t" \ - "lds r1, osc+3*%[mul]+%[fre]+1" "\n\t" \ - "add r0, r0 " "\n\t" \ - "adc r1, r1 " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "eor r0, r27 " "\n\t" \ - "sbrc r1, 6 " "\n\t" \ - "eor r0, r27 " "\n\t" \ - "sts osc+3*%[mul]+%[fre], r0 " "\n\t" \ - "sts osc+3*%[mul]+%[fre]+1, r1 " "\n\t" \ - \ - "lds r27, osc+3*%[mul]+%[vol] " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "lds r27, pcm " "\n\t" \ - "add r26, r27 " "\n\t" \ - "sts %[reg], r26 " "\n\t" \ - \ - "lds r27, cia_count+1 " "\n\t" \ - "lds r26, cia_count " "\n\t" \ - "sbiw r26, 1 " "\n\t" \ - "breq call_playroutine " "\n\t" \ - "sts cia_count+1, r27 " "\n\t" \ - "sts cia_count, r26 " "\n\t" \ - "rjmp 2f " "\n\t" \ - \ - "call_playroutine: " "\n\t" \ - \ - "lds r27, cia+1 " "\n\t" \ - "lds r26, cia " "\n\t" \ - "sts cia_count+1, r27 " "\n\t" \ - "sts cia_count, r26 " "\n\t" \ - \ - "sei " "\n\t" \ - "push r19 " "\n\t" \ - "push r20 " "\n\t" \ - "push r21 " "\n\t" \ - "push r22 " "\n\t" \ - "push r23 " "\n\t" \ - "push r24 " "\n\t" \ - "push r25 " "\n\t" \ - "push r30 " "\n\t" \ - "push r31 " "\n\t" \ - \ - "clr r1 " "\n\t" \ - "call ATM_playroutine " "\n\t" \ - \ - "pop r31 " "\n\t" \ - "pop r30 " "\n\t" \ - "pop r25 " "\n\t" \ - "pop r24 " "\n\t" \ - "pop r23 " "\n\t" \ - "pop r22 " "\n\t" \ - "pop r21 " "\n\t" \ - "pop r20 " "\n\t" \ - "pop r19 " "\n\t" \ - "2: " "\n\t" \ - "pop r1 " "\n\t" \ - "pop r0 " "\n\t" \ - "pop r26 " "\n\t" \ - "pop r27 " "\n\t" \ - "3: " "\n\t" \ - "pop r18 " "\n\t" \ - "out __SREG__, r2 " "\n\t" \ - "pop r2 " "\n\t" \ - "reti " "\n\t" \ - : \ - : [reg] "M" _SFR_MEM_ADDR(TARGET_REGISTER), \ - [mul] "M" (sizeof(Oscillator)), \ - [pha] "M" (offsetof(Oscillator, phase)), \ - [fre] "M" (offsetof(Oscillator, freq)), \ - [vol] "M" (offsetof(Oscillator, vol)) \ - ); \ -} -#else -#define ATMLIB_CONSTRUCT_ISR(TARGET_REGISTER,TARGET_REGISTER2) \ -uint16_t __attribute__((used)) cia, __attribute__((used)) cia_count; \ -ISR(TIMER4_OVF_vect, ISR_NAKED) { \ - asm volatile( \ - "push r2 " "\n\t" \ - "in r2, __SREG__ " "\n\t" \ - "push r18 " "\n\t" \ - "lds r18, half " "\n\t" \ - "com r18 " "\n\t" \ - "sts half, r18 " "\n\t" \ - "breq 1f " "\n\t" \ - "rjmp 3f " "\n\t" \ - "1: " "\n\t" \ - "push r27 " "\n\t" \ - "push r26 " "\n\t" \ - "push r0 " "\n\t" \ - "push r1 " "\n\t" \ - \ - "lds r18, osc+2*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+2*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+2*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+2*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+2*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+2*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "mov r27, r1 " "\n\t" \ - "sbrc r27, 7 " "\n\t" \ - "com r27 " "\n\t" \ - "lsl r27 " "\n\t" \ - "lds r26, osc+2*%[mul]+%[vol] " "\n\t" \ - "subi r27, 128 " "\n\t" \ - "muls r27, r26 " "\n\t" \ - "lsl r1 " "\n\t" \ - "mov r26, r1 " "\n\t" \ - \ - "lds r18, osc+0*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+0*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+0*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+0*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+0*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+0*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "mov r18, r1 " "\n\t" \ - "lsl r18 " "\n\t" \ - "and r18, r1 " "\n\t" \ - "lds r27, osc+0*%[mul]+%[vol] " "\n\t" \ - "sbrc r18, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "lds r18, osc+1*%[mul]+%[fre] " "\n\t" \ - "lds r0, osc+1*%[mul]+%[pha] " "\n\t" \ - "add r0, r18 " "\n\t" \ - "sts osc+1*%[mul]+%[pha], r0 " "\n\t" \ - "lds r18, osc+1*%[mul]+%[fre]+1" "\n\t" \ - "lds r1, osc+1*%[mul]+%[pha]+1" "\n\t" \ - "adc r1, r18 " "\n\t" \ - "sts osc+1*%[mul]+%[pha]+1, r1 " "\n\t" \ - \ - "lds r27, osc+1*%[mul]+%[vol] " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "ldi r27, 1 " "\n\t" \ - "lds r0, osc+3*%[mul]+%[fre] " "\n\t" \ - "lds r1, osc+3*%[mul]+%[fre]+1" "\n\t" \ - "add r0, r0 " "\n\t" \ - "adc r1, r1 " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "eor r0, r27 " "\n\t" \ - "sbrc r1, 6 " "\n\t" \ - "eor r0, r27 " "\n\t" \ - "sts osc+3*%[mul]+%[fre], r0 " "\n\t" \ - "sts osc+3*%[mul]+%[fre]+1, r1 " "\n\t" \ - \ - "lds r27, osc+3*%[mul]+%[vol] " "\n\t" \ - "sbrc r1, 7 " "\n\t" \ - "neg r27 " "\n\t" \ - "add r26, r27 " "\n\t" \ - \ - "lds r27, pcm " "\n\t" \ - "add r26, r27 " "\n\t" \ - "sts %[reg], r26 " "\n\t" \ - "sts %[reg2], r26 " "\n\t" \ - \ - "lds r27, cia_count+1 " "\n\t" \ - "lds r26, cia_count " "\n\t" \ - "sbiw r26, 1 " "\n\t" \ - "breq call_playroutine " "\n\t" \ - "sts cia_count+1, r27 " "\n\t" \ - "sts cia_count, r26 " "\n\t" \ - "rjmp 2f " "\n\t" \ - \ - "call_playroutine: " "\n\t" \ - \ - "lds r27, cia+1 " "\n\t" \ - "lds r26, cia " "\n\t" \ - "sts cia_count+1, r27 " "\n\t" \ - "sts cia_count, r26 " "\n\t" \ - \ - "sei " "\n\t" \ - "push r19 " "\n\t" \ - "push r20 " "\n\t" \ - "push r21 " "\n\t" \ - "push r22 " "\n\t" \ - "push r23 " "\n\t" \ - "push r24 " "\n\t" \ - "push r25 " "\n\t" \ - "push r30 " "\n\t" \ - "push r31 " "\n\t" \ - \ - "clr r1 " "\n\t" \ - "call ATM_playroutine " "\n\t" \ - \ - "pop r31 " "\n\t" \ - "pop r30 " "\n\t" \ - "pop r25 " "\n\t" \ - "pop r24 " "\n\t" \ - "pop r23 " "\n\t" \ - "pop r22 " "\n\t" \ - "pop r21 " "\n\t" \ - "pop r20 " "\n\t" \ - "pop r19 " "\n\t" \ - "2: " "\n\t" \ - "pop r1 " "\n\t" \ - "pop r0 " "\n\t" \ - "pop r26 " "\n\t" \ - "pop r27 " "\n\t" \ - "3: " "\n\t" \ - "pop r18 " "\n\t" \ - "out __SREG__, r2 " "\n\t" \ - "pop r2 " "\n\t" \ - "reti " "\n\t" \ - : \ - : [reg] "M" _SFR_MEM_ADDR(TARGET_REGISTER), \ - [reg2] "M" _SFR_MEM_ADDR(TARGET_REGISTER2), \ - [mul] "M" (sizeof(Oscillator)), \ - [pha] "M" (offsetof(Oscillator, phase)), \ - [fre] "M" (offsetof(Oscillator, freq)), \ - [vol] "M" (offsetof(Oscillator, vol)) \ - ); \ -} -#endif -#endif +#endif \ No newline at end of file