update ATMlib
Optimized Assembly code saving more bytes and saving a few cycles Moved and refactored assemby from ATMlib.h code to ATMlib.cpp fix muteChannel() and unMuteChannel() so (un)mutes channel properly Added C++ equivalent ISR code
This commit is contained in:
parent
1cc93f05d7
commit
315c3c45e9
|
@ -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;
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue