View difference between Paste ID: 6tj3bK3U and xfPhvv4t
SHOW: | | - or go back to the newest paste.
1
; sound generation:
2
; two output channels buffers
3
; four software channels
4
; first two hard-panned to left, second two hard-panned to right
5
; each channel switchable between either pulse, triangle, saw, and noise
6
; 16-bit oscilators and frequencies for each channel
7
; 4-bit fine tuners for each channel
8
; 8-bit volumes for each channel
9
; 8-bit duty cycle settings for each channel
10
; enable bits for each channel
11
;
12
; music generation:
13
; tempo
14
; ticks per frame
15
; repeat section
16
; each channel has three notes that are arpeggiated to modulate the target frequency
17
; each channel has its own target frequency
18
; each channel has its own frequency sweep speed which is the amount added or substracted from the channel frequency per tick until the target frequency is reached
19
; each channel has its own target volume
20
; each channel has its own volume sweep speed which is the amount added or substracted from the channel volume per tick until the target volume is reached
21
; each channel has its own vibrato settings split between depth and rate which control the effective target frequency
22
; each channel has its own tremolo settings split between depth and rate which control the effective target volume
23
; each channel has its own instrumnt which is a list of four effects to be applied per tick
24
;
25
; song format:
26
; 0x00 - tempo
27
; 0x01 - ticks per frame
28
; 0x02 - repeat low
29
; 0x03 - repeat high
30
; [0x10 - 0x4F] - instruments
31
; [0x50 - end] - frames
32
;
33
; instrument format:
34
; 0x00 - effect 1
35
; 0x01 - effect 2
36
; 0x02 - effect 3
37
; 0x03 - effect 4
38
;
39
; effect format:
40
; first nybble - effect
41
; second nybble - argument
42
;
43
; frame format:
44
; first byte - note
45
; second byte - volume
46
; third byte - instrument
47
; fourth byte - arppegio
48
;
49
; note format:
50
; first nybble - note
51
; second nybble - octave
52
;
53
; notes:
54
; 0x0 - null
55
; 0x1 - same as root (for arppegio notes)
56
; 0x2 - stop
57
; 0x3 - revive
58
; 0x4 - C
59
; 0x5 - C#
60
; 0x6 - D
61
; 0x7 - D#
62
; 0x8 - E
63
; 0x9 - F
64
; 0xA - F#
65
; 0xB - G
66
; 0xC - G#
67
; 0xD - A
68
; 0xE - A#
69
; 0xF - B
70
;
71
; arppegio format:
72
; first nybble - note 2 (above octave of note 1)
73
; second nybble - note 3 (above octave of note 1)
74
75
.define NOTE_C 262
76
.define NOTE_Cs 277
77
.define NOTE_D 294
78
.define NOTE_Ds 311
79
.define NOTE_E 330
80
.define NOTE_F 349
81
.define NOTE_Fs 370
82
.define NOTE_G 392
83
.define NOTE_Gs 415
84
.define NOTE_A 440
85
.define NOTE_As 466
86
.define NOTE_B 494
87
88
.def LEFT_BUF = r2
89
.def RIGHT_BUF = r3
90
91
.def CHAN1_OSCL = r4
92
.def CHAN1_OSCH = r5
93
.def CHAN2_OSCL = r6
94
.def CHAN2_OSCH = r7
95
.def CHAN3_OSCL = r8
96
.def CHAN3_OSCH = r9
97
.def CHAN4_OSCL = r10
98
.def CHAN4_OSCH = r11
99
100
.def CHAN1_FRQL = r12
101
.def CHAN1_FRQH = r13
102
.def CHAN2_FRQL = r14
103
.def CHAN2_FRQH = r15
104
.def CHAN3_FRQL = r24
105
.def CHAN3_FRQH = r25
106
.def CHAN4_FRQL = r26
107
.def CHAN4_FRQH = r27
108
109
.def NOISEL = r0
110
.def NOISEH = r1
111
112
.def EFF_DIR = r18
113
114
.NOLIST
115
.include "m48def.inc"
116
.LIST
117
118
.cseg
119
.org 0x00
120
	rjmp start
121
122
.org 0x09
123
	rjmp timer
124
	
125
.org 0x40
126
start:
127
	ldi r16, LOW(RAMEND)
128
	out spl, r16
129
	ldi r16, HIGH(RAMEND)
130
	out sph, r16
131
	
132
	ldi r16, 1
133
	sts TIMSK2, r16
134
	ldi r16, 0b001
135
	sts TCCR2B, r16
136
	
137
	ldi r16, 0xFF
138
	out ddrd, r16
139
	out ddrc, r16
140
	
141
	ldi r16, 0xFF
142
	mov LEFT_BUF, r16
143
	mov RIGHT_BUF, r16
144
	
145
	ldi r16, 0x01
146
	mov NOISEL, r16
147
	ldi r16, 0x00
148
	mov NOISEH, r16
149
	
150
	ldi r16, 0b0000
151
	sts enable, r16
152
	
153
	ldi r16, 0x08
154
	sts tempo, r16
155
	ldi r16, 0x06
156
	sts speed, r16
157
	
158
	ldi r16, 0x0F
159
	sts chan1_vib, r16
160
	sts chan2_vib, r16
161
	sts chan3_vib, r16
162
	sts chan4_vib, r16
163
	
164
	ldi r16, 0x0F
165
	sts chan1_trm, r16
166
	sts chan2_trm, r16
167
	sts chan3_trm, r16
168-
	ldi r16, 0x45
168+
	sts chan4_trm, r16
169
	
170
	ldi r16, 0xFF
171
	sts chan1_vol, r16
172
	sts chan2_vol, r16
173
	sts chan3_vol, r16
174
	sts chan4_vol, r16
175
	
176-
	ldi r16, LOW(0)
176+
177-
	ldi r17, HIGH(0)
177+
	sts chan1_tvol, r16
178-
	mov CHAN1_FRQL, r16
178+
	sts chan2_tvol, r16
179-
	mov CHAN1_FRQH, r17
179+
	sts chan3_tvol, r16
180
	sts chan4_tvol, r16
181-
	ldi r16, LOW(0)
181+
182-
	ldi r17, HIGH(0)
182+
183-
	mov CHAN2_FRQL, r16
183+
184-
	mov CHAN2_FRQH, r17
184+
185
	sts chan3_dut, r16
186-
	ldi r16, LOW(0)
186+
187-
	ldi r17, HIGH(0)
187+
188-
	mov CHAN3_FRQL, r16
188+
	ldi r16, 0x44
189-
	mov CHAN3_FRQH, r17
189+
190
	ldi r16, 0x00
191-
	ldi r16, LOW(0)
191+
192-
	ldi r17, HIGH(0)
192+
193-
	mov CHAN4_FRQL, r16
193+
194-
	mov CHAN4_FRQH, r17
194+
195
	
196
	sei
197
198
loop:
199
	rjmp loop
200
201
note_freq:
202
	mov r16, r19
203
	lsr r16
204
	lsr r16
205
	lsr r16
206
	lsr r16
207
	cpi r16, 0x04
208
	breq setc
209
	cpi r16, 0x05
210
	breq setcs
211
	cpi r16, 0x06
212
	breq setd
213
	cpi r16, 0x07
214
	breq setds
215
	cpi r16, 0x08
216
	breq sete
217
	cpi r16, 0x09
218
	breq setf
219
	cpi r16, 0x0A
220
	breq setfs
221
	cpi r16, 0x0B
222
	breq setg
223
	cpi r16, 0x0C
224
	breq setgs
225
	cpi r16, 0x0D
226
	breq seta
227
	cpi r16, 0x0E
228
	breq setas
229
	cpi r16, 0x0F
230
	breq setb
231
	ret
232
setc:
233
	ldi r16, LOW(NOTE_C)
234
	ldi r17, HIGH(NOTE_C)
235
	rjmp skip4
236
setcs:
237
	ldi r16, LOW(NOTE_Cs)
238
	ldi r17, HIGH(NOTE_Cs)
239
	rjmp skip4
240
setd:
241
	ldi r16, LOW(NOTE_D)
242
	ldi r17, HIGH(NOTE_D)
243
	rjmp skip4
244
setds:
245
	ldi r16, LOW(NOTE_Ds)
246
	ldi r17, HIGH(NOTE_Ds)
247
	rjmp skip4
248
sete:
249
	ldi r16, LOW(NOTE_E)
250
	ldi r17, HIGH(NOTE_E)
251
	rjmp skip4
252
setf:
253
	ldi r16, LOW(NOTE_F)
254
	ldi r17, HIGH(NOTE_F)
255
	rjmp skip4
256
setfs:
257
	ldi r16, LOW(NOTE_Fs)
258
	ldi r17, HIGH(NOTE_Fs)
259
	rjmp skip4
260
setg:
261
	ldi r16, LOW(NOTE_G)
262
	ldi r17, HIGH(NOTE_G)
263
	rjmp skip4
264
setgs:
265
	ldi r16, LOW(NOTE_Gs)
266
	ldi r17, HIGH(NOTE_Gs)
267
	rjmp skip4
268
seta:
269
	ldi r16, LOW(NOTE_A)
270
	ldi r17, HIGH(NOTE_A)
271
	rjmp skip4
272
setas:
273
	ldi r16, LOW(NOTE_As)
274
	ldi r17, HIGH(NOTE_As)
275
	rjmp skip4
276
setb:
277
	ldi r16, LOW(NOTE_B)
278
	ldi r17, HIGH(NOTE_B)
279
	rjmp skip4
280
skip4:
281
	andi r19, 0x0F
282
	cpi r19, 0x01
283
	breq seto1
284
	cpi r19, 0x02
285
	breq seto2
286
	cpi r19, 0x03
287
	breq seto3
288
	cpi r19, 0x04
289
	breq seto4
290
	cpi r19, 0x05
291
	breq seto5
292
	cpi r19, 0x06
293
	breq seto6
294
	cpi r19, 0x07
295
	breq seto7
296
	cpi r19, 0x08
297
	breq seto8
298
	ret
299
seto1:
300
	lsr r17
301
	ror r16
302
	lsr r17
303
	ror r16
304
	lsr r17
305
	ror r16
306
	ret
307
seto2:
308
	lsr r17
309
	ror r16
310
	lsr r17
311
	ror r16
312
	ret
313
seto3:
314
	lsr r17
315
	ror r16
316
	ret
317
seto4:
318
	ret
319
seto5:
320
	lsl r16
321
	rol r17
322
	ret
323
seto6:
324
	lsl r16
325
	rol r17
326
	lsl r16
327
	rol r17
328
	ret
329
seto7:
330
	lsl r16
331
	rol r17
332
	lsl r16
333
	rol r17
334
	lsl r16
335
	rol r17
336
	ret
337
seto8:
338
	lsl r16
339
	rol r17
340
	lsl r16
341
	rol r17
342
	lsl r16
343
	rol r17
344
	lsl r16
345
	rol r17
346
	ret
347
	
348
track:
349
	ret
350
	
351
arpeggio:
352
	mov r21, r19
353
	andi r21, 0xF0
354
	cpi r16, 1
355
	breq first
356
	cpi r16, 2
357
	breq second
358
	ret
359
first:
360
	andi r20, 0xF0
361
	andi r19, 0x0F
362
	cpi r20, 4
363
	brlo nope2
364
	cp r21, r20
365
	brlo nope
366
	inc r19
367
nope:
368
	or r19, r20
369
	ret
370
second:
371
	lsl r20
372
	lsl r20
373
	lsl r20
374
	lsl r20
375
	andi r19, 0x0F
376
	cpi r20, 4
377
	brlo nope2
378
	cp r21, r20
379
	brlo nope
380
	inc r19
381
nope2:
382
	or r19, r21
383
	ret
384
385
music:
386
	clr r18
387
	sts music_timer, r18
388
	sts music_timer + 1, r18
389
	
390
	lds r16, tick_timer
391
	mov r17, r16
392
	lsr r17
393
	lsr r17
394
	lsr r17
395
	lsr r17
396
	andi r16, 0x0F
397
	inc r17
398
	lds r18, speed
399
	cp r17, r18
400
	brlo no_track
401
	rcall track
402
	clr r17
403
	rjmp okay
404
no_track:
405
	lsl r17
406
	lsl r17
407
	lsl r17
408
	lsl r17
409
okay:
410
	lds r18, fine_tune
411
412
	push r17
413
	push r16
414
	
415
	lds r19, chan1_notes
416
	lds r20, chan1_notes + 1
417
	rcall arpeggio
418
	rcall note_freq
419
	
420-
	mov CHAN1_FRQL, r16
420+
	lds r21, chan1_vib
421-
	mov CHAN1_FRQH, r17
421+
	mov r22, CHAN1_FRQL
422
	mov r23, CHAN1_FRQH
423
	
424
	rcall sweep
425
	
426
	mov CHAN1_FRQL, r22
427
	mov CHAN1_FRQH, r23
428
	
429
	mov r19, r18
430
	andi r19, 0x0F
431
	add CHAN1_FRQL, r19
432
	
433
	pop r16
434
	push r16
435-
	mov CHAN2_FRQL, r16
435+
436-
	mov CHAN2_FRQH, r17
436+
437
	lds r20, chan2_notes + 1
438
	rcall arpeggio
439
	rcall note_freq
440
	
441
	lds r21, chan2_vib
442
	mov r22, CHAN2_FRQL
443
	mov r23, CHAN2_FRQH
444
	
445
	rcall sweep
446
	
447
	mov CHAN2_FRQL, r22
448
	mov CHAN2_FRQH, r23
449
	
450
	lsr r18
451
	lsr r18
452
	lsr r18
453
	lsr r18
454-
	mov CHAN3_FRQL, r16
454+
455-
	mov CHAN3_FRQH, r17
455+
456
	lds r18, fine_tune + 1
457
	
458
	pop r16
459
	push r16
460
	
461
	lds r19, chan3_notes
462
	lds r20, chan3_notes + 1
463
	rcall arpeggio
464
	rcall note_freq
465
	
466
	lds r21, chan3_vib
467
	mov r22, CHAN3_FRQL
468
	mov r23, CHAN3_FRQH
469-
	mov CHAN4_FRQL, r16
469+
470-
	mov CHAN4_FRQH, r17
470+
	rcall sweep
471
	
472
	mov CHAN3_FRQL, r22
473
	mov CHAN3_FRQH, r23
474
	
475
	mov r19, r18
476
	andi r19, 0x0F
477
	add CHAN3_FRQL, r19
478
	
479
	pop r16
480
	push r16
481
	
482
	lds r19, chan4_notes
483
	lds r20, chan4_notes + 1
484
	rcall arpeggio
485
	rcall note_freq
486
	
487
	lds r21, chan4_vib
488
	mov r22, CHAN4_FRQL
489
	mov r23, CHAN4_FRQH
490
	
491
	rcall sweep
492
	
493
	mov CHAN4_FRQL, r22
494
	mov CHAN4_FRQH, r23
495
	
496
	lsr r18
497
	lsr r18
498
	lsr r18
499
	lsr r18
500
	add CHAN4_FRQL, r18
501
	
502
	pop r16
503
	pop r17
504
	
505
	inc r16
506
	cpi r16, 3
507
	brlo lower
508
	clr r16
509
lower:
510
	or r17, r16
511
	sts tick_timer, r17
512
	
513
	lds r16, chan1_trm
514
	lds r17, chan1_vol
515
	lds r18, chan1_tvol
516
	rcall vol_sweep
517
	sts chan1_vol, r17
518
	
519
	lds r16, chan2_trm
520
	lds r17, chan2_vol
521
	lds r18, chan2_tvol
522
	rcall vol_sweep
523
	sts chan2_vol, r17
524
	
525
	lds r16, chan3_trm
526
	lds r17, chan3_vol
527
	lds r18, chan3_tvol
528
	rcall vol_sweep
529
	sts chan3_vol, r17
530
	
531
	lds r16, chan4_trm
532
	lds r17, chan4_vol
533
	lds r18, chan4_tvol
534
	rcall vol_sweep
535
	sts chan4_vol, r17
536
	
537
	ret
538
539
vol_sweep:
540
	lsr r16
541
	lsr r16
542
	lsr r16
543
	lsr r16
544
	cpi r16, 0
545
	breq vol_equal
546
	cp r17, r18
547
	brlo vol_smaller
548
	cp r18, r17
549
	brlo vol_bigger
550
	rjmp vol_equal
551
vol_smaller:
552
	add r17, r16
553
	cp r18, r17
554
	brlo vol_equal
555
	ret
556
vol_bigger:
557
	sub r17, r16
558
	cp r17, r18
559
	brlo vol_equal
560
	ret
561
vol_equal:
562
	mov r17, r18
563
	ret
564
565
sweep:
566
	lsr r21
567
	lsr r21
568
	lsr r21
569
	lsr r21
570
	cpi r21, 0
571
	breq equal
572
	cp r23, r17
573
	brlo smaller
574
	cp r17, r23
575
	brlo bigger
576
	cp r22, r16
577
	brlo smaller
578
	cp r16, r22
579
	brlo bigger
580
	rjmp equal
581
bigger:
582
	sub r22, r21
583
	brcc yeah
584
	dec r23
585
yeah:
586
	rjmp done_big
587
done_big:
588
	cp r23, r17
589
	brlo equal
590
	cp r17, r23
591
	brlo return2
592
	cp r22, r16
593
	brlo equal
594
	rjmp return2
595
smaller:
596
	clr r19
597
	add r22, r21
598
	adc r23, r19
599
	rjmp done_small
600
done_small:
601
	cp r23, r17
602
	brlo return2
603
	cp r17, r23
604
	brlo equal
605
	cp r22, r16
606
	brlo return2
607
	cp r16, r22
608
	brlo equal
609
	rjmp return2
610
equal:
611
	mov r22, r16
612
	mov r23, r17
613
return2:
614
	ret
615
616
timer:
617
	mov r16, LEFT_BUF
618
	lsr r16
619
	lsr r16
620
	mov r17, RIGHT_BUF
621
	lsr r17
622
	lsr r17
623
	out portd, r16
624
	out portc, r17
625
	
626
	lds r16, music_timer
627
	lds r17, music_timer + 1
628
	ldi r18, 0
629
	ldi r19, 1
630
	add r16, r19
631
	adc r17, r18
632
	sts music_timer, r16
633
	sts music_timer + 1, r17
634
	lds r18, tempo
635
	cp r17, r18
636
	brlo no_music
637
	rcall music
638
	
639
no_music:
640
	clr LEFT_BUF
641
	clr RIGHT_BUF
642
	
643
	add CHAN1_OSCL, CHAN1_FRQL
644
	adc CHAN1_OSCH, CHAN1_FRQH
645
	add CHAN2_OSCL, CHAN2_FRQL
646
	adc CHAN2_OSCH, CHAN2_FRQH
647
	add CHAN3_OSCL, CHAN3_FRQL
648
	adc CHAN3_OSCH, CHAN3_FRQH
649
	add CHAN4_OSCL, CHAN4_FRQL
650
	adc CHAN4_OSCH, CHAN4_FRQH
651
	
652
	lds r16, waveform
653
	lds r22, enable
654
	
655
	mov r18, r16
656
	andi r18, 0b00000011
657
	mov r19, CHAN1_OSCH
658
	lds r20, chan1_vol
659
	lds r21, chan1_dut
660
	rcall generate
661
	sbrc r22, 0
662
	add LEFT_BUF, r17
663
	
664
	lsr r16
665
	lsr r16
666
	mov r18, r16
667
	andi r18, 0b00000011
668
	mov r19, CHAN2_OSCH
669
	lds r20, chan2_vol
670
	lds r21, chan2_dut
671
	rcall generate
672
	sbrc r22, 1
673
	add LEFT_BUF, r17
674
	
675
	lsr r16
676
	lsr r16
677
	mov r18, r16
678
	andi r18, 0b00000011
679
	mov r19, CHAN3_OSCH
680
	lds r20, chan3_vol
681
	lds r21, chan3_dut
682-
chan1_dir: .byte 1
682+
683-
chan2_dir: .byte 1
683+
684-
chan3_dir: .byte 1
684+
685-
chan4_dir: .byte 1
685+
686
	lsr r16
687
	lsr r16
688
	mov r18, r16
689
	andi r18, 0b00000011
690
	mov r19, CHAN4_OSCH
691
	lds r20, chan4_vol
692
	lds r21, chan4_dut
693
	rcall generate
694
	sbrc r22, 3
695
	add RIGHT_BUF, r17
696
	
697
	reti
698
699
generate:
700
	clr r17
701
	cpi r18, 0b00
702
	breq gen_pulse
703
	cpi r18, 0b01
704
	breq gen_triangle
705
	cpi r18, 0b10
706
	breq gen_saw
707
	cpi r18, 0b11
708
	breq gen_noise
709
	ret
710
	
711
gen_pulse:
712
	cp r19, r21
713
	brlo return
714
	mov r17, r20
715
	lsr r17
716
	lsr r17
717
	ret
718
	
719
gen_triangle:
720
	mov r17, r19
721
	sbrc r19, 7
722
	com r17
723
	rjmp apply_volume
724
	ret
725
	
726
gen_saw:
727
	mov r17, r19
728
	lsr r17
729
	lsr r17
730
	rjmp apply_volume
731
	ret
732
	
733
gen_noise:
734
	clr r21
735
	clr r19
736
	sbrc NOISEH, 6
737
	ser r21
738
	sbrc NOISEL, 3
739
	ser r19
740
	eor r19, r21
741
	clr r21
742
	lsl NOISEH
743
	lsl NOISEL
744
	adc NOISEH, r21
745
	sbrc r19, 0
746
	inc NOISEL
747
	mov r17, NOISEL
748
	lsr r17
749
	rjmp apply_volume
750
	ret
751
	
752
apply_volume:
753
	sbrc r20, 7
754
	rjmp return
755
	lsr r17
756
	sbrc r20, 6
757
	rjmp return
758
	lsr r17
759
	sbrc r20, 5
760
	rjmp return
761
	lsr r17
762
	sbrc r20, 4
763
	rjmp return
764
	lsr r17
765
	sbrc r20, 3
766
	rjmp return
767
	lsr r17
768
	sbrc r20, 2
769
	rjmp return
770
	lsr r17
771
	sbrc r20, 1
772
	rjmp return
773
	lsr r17
774
return:
775
	ret
776
777
.dseg
778
chan1_vol: .byte 1
779
chan2_vol: .byte 1
780
chan3_vol: .byte 1
781
chan4_vol: .byte 1
782
783
chan1_dut: .byte 1
784
chan2_dut: .byte 1
785
chan3_dut: .byte 1
786
chan4_dut: .byte 1
787
788
fine_tune: .byte 2
789
waveform: .byte 1
790
enable: .byte 1
791
music_timer: .byte 2
792
tick_timer: .byte 1
793
794
tempo: .byte 1
795
speed: .byte 1
796
797
chan1_tvol: .byte 1
798
chan2_tvol: .byte 1
799
chan3_tvol: .byte 1
800
chan4_tvol: .byte 1
801
802
chan1_notes: .byte 2
803
chan2_notes: .byte 2
804
chan3_notes: .byte 2
805
chan4_notes: .byte 2
806
807
chan1_vib: .byte 1
808
chan2_vib: .byte 1
809
chan3_vib: .byte 1
810
chan4_vib: .byte 1
811
812
chan1_trm: .byte 1
813
chan2_trm: .byte 1
814
chan3_trm: .byte 1
815
chan4_trm: .byte 1