noiseplug/avr/noiseplug.s
Joachim Fenkes fab67dc800 asm arpeggio
2012-08-11 14:32:20 +02:00

305 lines
4.5 KiB
ArmAsm

.global __vectors
SREG = 0x3F
CCP = 0x3C
SMCR = 0x3A
CLKPSR = 0x36
TCCR0A = 0x2E
TCCR0B = 0x2D
TCCR0C = 0x2C
TIMSK0 = 0x2B
TIFR0 = 0x2A
OCR0AL = 0x26
PUEB = 0x03
PORTB = 0x02
DDRB = 0x01
PINB = 0x00
.section .bss
.comm int_ctr, 1
.comm i, 3
.comm lead1, 4
.comm lead2, 4
.comm lead3, 4
.comm bassosc, 2
.comm bassflange, 2
.comm arposc, 2
.comm boost, 1
; leaves 9 bytes for stack
.section .text
__vectors:
NULL:
clr r16
ldi r17, 0xD8
out PUEB, r16
rjmp main_cont
.type __vector_4, @function
__vector_4:
push r16
push r24
in r16, SREG
lds r24,int_ctr
subi r24,lo8(-(1))
andi r24,lo8(3)
sts int_ctr,r24
out SREG,r16
pop r24
pop r16
reti
.size __vector_4, .-__vector_4
main_cont:
clr r31
ldi r30, 0x40
clearsram:
st Z+, r16
sbrs r30, 5
rjmp clearsram
out CCP, r17
out CLKPSR, r16
ldi r17, 5
out DDRB, r17
ldi r17, 0x81
out TCCR0A, r17
ldi r17, 0x09
out TCCR0B, r17
ldi r17, 1
out SMCR, r17
out TIMSK0, r17
sei
out TIFR0, r17
mainloop:
sleep
clr r16
lds r17, int_ctr
tst r17
brne mainloop
sbi PORTB, 2
lds r17, i
lds r18, i+1
lds r19, i+2
subi r19, 0xff
sbci r18, 0xff
sbci r17, 0xff
; if ((i >> 13) == 76) i = 16 << 13;
mov r20, r18
rol r20
mov r20, r17
rol r20
subi r20, 0x13
brne norestart
ldi r17, 2
clr r18
norestart:
sts i, r17
sts i+1, r18
sts i+2, r19
; ==== BASS ====
; bassptr(r20) = (i >> 13) & 0xF
mov r20, r17
ror r20
mov r20, r18
ror r20
swap r20
andi r20, 0xF
; if (i >> 19) & 1: bassptr |= 0x10
sbrc r17, 3
ori r20, 0x10
; note = notes[bassline[bassptr]]
ldi r31, hi8(bassline+0x4000)
ldi r30, lo8(bassline)
add r30, r20
ld r20, Z
ldi r30, lo8(notes)
add r30, r20
ld r21, Z+
ld r20, Z
; if (bassbeat[(i >> 10) & 7]): note <<= 1
mov r22, r18
lsr r22
lsr r22
andi r22, 7
ldi r30, lo8(bassbeat)
add r30, r22
ld r22, Z
tst r22 ; assuming this resets C
breq nobassbeat
rol r21
rol r20
nobassbeat:
; bassosc += note, ret = (bassosc >> 8) & 0x7F
lds r22, bassosc
lds r23, bassosc + 1
add r23, r21
adc r22, r20
sts bassosc, r22
sts bassosc + 1, r23
mov r24, r22
andi r24, 0x7F
; bassflange += note + 1, ret += (bassflange >> 8) & 0x7F
lds r22, bassflange
lds r23, bassflange + 1
inc r21
add r23, r21
adc r22, r20
sts bassflange, r22
sts bassflange + 1, r23
andi r22, 0x7F
add r24, r22
; if ((i >> 6) & 0xF) == 0xF: sample += (bass >> 2)
lsr r24
lsr r24
mov r20, r18
andi r20, 3
subi r20, 3
brne addbass
mov r20, r19
andi r20, 0xC0
subi r20, 0xC0
breq noaddbass
addbass:
add r16, r24
noaddbass:
; ==== ARPEGGIO ====
; arpptr(r30) = arpseq1[arpseq2[i >> 16]][(i >> 14) & 3]
mov r30, r17
subi r30, lo8(NULL-arpseq2)
ld r30, Z
lsl r30
lsl r30
mov r20, r18
swap r20
lsr r20
lsr r20
andi r20, 3
or r30, r20
subi r30, lo8(NULL-arpseq1)
ld r30, Z
; if (!(i & (1 << 13))): arpptr >>= 14
sbrs r18, 5
swap r30
; arpptr = arpeggio[arpptr & 0xF][(i >> 8) & 1]
andi r30, 0xF
lsl r30
mov r20, r18
andi r20, 1
or r30, r20
subi r30, lo8(NULL-arpeggio)
ld r30, Z
; if (!(i & 0x80)): arpptr >>= 14
sbrs r19, 7
swap r30
; note = arpnotes[arpptr & 0xF]
andi r30, 0xF
lsl r30
subi r30, lo8(NULL-arpnotes)
ld r21, Z+
ld r20, Z
; arp_osc += note
lds r22, arposc
lds r23, arposc + 1
add r23, r21
adc r22, r20
sts arposc, r22 ; keep r22 for later!
sts arposc + 1, r23
; if (!(i >> 17)): break arp
mov r20, r17
lsr r20
breq noarp
; r20 = arptiming[(i >> 12) & 3]
mov r30, r18
swap r30
andi r30, 3
subi r30, lo8(NULL-arptiming)
ld r20, Z
; if (!((r20 << ((i >> 9) & 7)) & 0x80)): break arp
mov r21, r18
lsr r21
andi r21, 7
breq arptiming_noshift
arptiming_shift:
lsl r20
subi r21, 1
brne arptiming_shift
arptiming_noshift:
sbrs r20, 7
rjmp noarp
; if (arp_osc & (1 << 12)): sample += 35;
sbrc r22, 4
subi r16, -35
noarp:
out OCR0AL, r16
cbi PORTB, 2
rjmp mainloop
.org 0x300
notes:
.word -1, 134, 159, 179, 201
arpnotes:
.word 213, 239, 268, 301, 319, 358, 401, 425, 451, 477, 536, 601, 637, 715
bassline:
.byte 14, 14, 18, 12, 14, 14, 20, 12, 14, 14, 18, 8, 10, 10, 4, 8
.byte 10, 10, 12, 12, 14, 14, 6, 6, 10, 10, 12, 12
bassbeat:
.byte 0, 0, 1, 0, 0, 1, 0, 1
arpseq1:
.byte 0x00, 0x12, 0x00, 0x62
.byte 0x00, 0x12, 0x00, 0x17
.byte 0x00, 0x12, 0x00, 0x12
.byte 0x33, 0x22, 0x00, 0x45
arpseq2:
.byte 0, 1, 0, 1, 0, 1, 0, 2, 3, 3
arptiming:
.byte 0x0C, 0x30, 0xFB, 0x0C
arpeggio:
.byte 0x24, 0x6A
.byte 0x46, 0x9C
.byte 0x13, 0x59
.byte 0x02, 0x47
.byte 0x24, 0x59
.byte 0x24, 0x58
.byte 0x57, 0xAD
.byte 0x35, 0x9B