View difference between Paste ID: xfPhvv4t and BMLP9AGN
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-
; each channel has its own extra effect
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
.NOLIST
113
.include "m48def.inc"
114
.LIST
115
116
.cseg
117
.org 0x00
118
	rjmp start
119
120
.org 0x09
121
	rjmp timer
122
	
123
.org 0x40
124
start:
125
	ldi r16, LOW(RAMEND)
126
	out spl, r16
127
	ldi r16, HIGH(RAMEND)
128
	out sph, r16
129
	
130
	ldi r16, 1
131
	sts TIMSK2, r16
132
	ldi r16, 0b001
133
	sts TCCR2B, r16
134
	
135
	ldi r16, 0xFF
136-
	ldi r16, 0b0101
136+
137
	out ddrc, r16
138
	
139
	ldi r16, 0xFF
140
	mov LEFT_BUF, r16
141
	mov RIGHT_BUF, r16
142
	
143
	ldi r16, 0x01
144
	mov NOISEL, r16
145-
	ldi r16, 0x10
145+
146
	mov NOISEH, r16
147
	
148
	ldi r16, 0b0000
149
	sts enable, r16
150
	
151-
	ldi r16, 0b11111101
151+
	ldi r16, 0x08
152
	sts tempo, r16
153
	ldi r16, 0x06
154-
	ldi r16, LOW(392)
154+
	sts speed, r16
155-
	ldi r17, HIGH(392)
155+
156
	ldi r16, 0x80
157
	sts chan1_vol, r16
158
	sts chan2_vol, r16
159-
	ldi r16, LOW(294)
159+
160-
	ldi r17, HIGH(294)
160+
161
	
162
	ldi r16, 0x80
163
	sts chan1_dut, r16
164-
	ldi r16, LOW(349)
164+
165-
	ldi r17, HIGH(349)
165+
166
	sts chan4_dut, r16
167
	
168
	ldi r16, 0x45
169-
	ldi r16, LOW(494)
169+
	sts chan1_notes, r16
170-
	ldi r17, HIGH(494)
170+
171
	sts chan1_notes + 1, r16
172
	
173
	ldi r16, 0b00000000
174
	sts waveform, r16
175
	
176
	ldi r16, LOW(0)
177
	ldi r17, HIGH(0)
178
	mov CHAN1_FRQL, r16
179
	mov CHAN1_FRQH, r17
180
	
181
	ldi r16, LOW(0)
182
	ldi r17, HIGH(0)
183
	mov CHAN2_FRQL, r16
184
	mov CHAN2_FRQH, r17
185
	
186
	ldi r16, LOW(0)
187
	ldi r17, HIGH(0)
188
	mov CHAN3_FRQL, r16
189
	mov CHAN3_FRQH, r17
190
	
191
	ldi r16, LOW(0)
192
	ldi r17, HIGH(0)
193
	mov CHAN4_FRQL, r16
194
	mov CHAN4_FRQH, r17
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-
enable: .byte 1
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
421
	mov CHAN1_FRQH, r17
422
	
423
	mov r19, r18
424
	andi r19, 0x0F
425
	add CHAN1_FRQL, r19
426
	
427
	pop r16
428
	push r16
429
	
430
	lds r19, chan2_notes
431
	lds r20, chan2_notes + 1
432
	rcall arpeggio
433
	rcall note_freq
434
	
435
	mov CHAN2_FRQL, r16
436
	mov CHAN2_FRQH, r17
437
	
438
	lsr r18
439
	lsr r18
440
	lsr r18
441
	lsr r18
442
	add CHAN2_FRQL, r18
443
	
444
	lds r18, fine_tune + 1
445
	
446
	pop r16
447
	push r16
448
	
449
	lds r19, chan3_notes
450
	lds r20, chan3_notes + 1
451
	rcall arpeggio
452
	rcall note_freq
453
	
454
	mov CHAN3_FRQL, r16
455
	mov CHAN3_FRQH, r17
456
	
457
	mov r19, r18
458
	andi r19, 0x0F
459
	add CHAN3_FRQL, r19
460
	
461
	pop r16
462
	push r16
463
	
464
	lds r19, chan4_notes
465
	lds r20, chan4_notes + 1
466
	rcall arpeggio
467
	rcall note_freq
468
	
469
	mov CHAN4_FRQL, r16
470
	mov CHAN4_FRQH, r17
471
	
472
	lsr r18
473
	lsr r18
474
	lsr r18
475
	lsr r18
476
	add CHAN4_FRQL, r18
477
	
478
	pop r16
479
	pop r17
480
	
481
	inc r16
482
	cpi r16, 3
483
	brlo lower
484
	clr r16
485
lower:
486
	or r17, r16
487
	sts tick_timer, r17
488
	
489
	ret
490
491
timer:
492
	mov r16, LEFT_BUF
493
	lsr r16
494
	lsr r16
495
	mov r17, RIGHT_BUF
496
	lsr r17
497
	lsr r17
498
	out portd, r16
499
	out portc, r17
500
	
501
	lds r16, music_timer
502
	lds r17, music_timer + 1
503
	ldi r18, 0
504
	ldi r19, 1
505
	add r16, r19
506
	adc r17, r18
507
	sts music_timer, r16
508
	sts music_timer + 1, r17
509
	lds r18, tempo
510
	cp r17, r18
511
	brlo no_music
512
	rcall music
513
	
514
no_music:
515
	clr LEFT_BUF
516
	clr RIGHT_BUF
517
	
518
	add CHAN1_OSCL, CHAN1_FRQL
519
	adc CHAN1_OSCH, CHAN1_FRQH
520
	add CHAN2_OSCL, CHAN2_FRQL
521
	adc CHAN2_OSCH, CHAN2_FRQH
522
	add CHAN3_OSCL, CHAN3_FRQL
523
	adc CHAN3_OSCH, CHAN3_FRQH
524
	add CHAN4_OSCL, CHAN4_FRQL
525
	adc CHAN4_OSCH, CHAN4_FRQH
526
	
527
	lds r16, waveform
528
	lds r22, enable
529
	
530
	mov r18, r16
531
	andi r18, 0b00000011
532
	mov r19, CHAN1_OSCH
533
	lds r20, chan1_vol
534
	lds r21, chan1_dut
535
	rcall generate
536
	sbrc r22, 0
537
	add LEFT_BUF, r17
538
	
539
	lsr r16
540
	lsr r16
541
	mov r18, r16
542
	andi r18, 0b00000011
543
	mov r19, CHAN2_OSCH
544
	lds r20, chan2_vol
545
	lds r21, chan2_dut
546
	rcall generate
547
	sbrc r22, 1
548
	add LEFT_BUF, r17
549
	
550
	lsr r16
551
	lsr r16
552
	mov r18, r16
553
	andi r18, 0b00000011
554
	mov r19, CHAN3_OSCH
555
	lds r20, chan3_vol
556
	lds r21, chan3_dut
557
	rcall generate
558
	sbrc r22, 2
559
	add RIGHT_BUF, r17
560
	
561
	lsr r16
562
	lsr r16
563
	mov r18, r16
564
	andi r18, 0b00000011
565
	mov r19, CHAN4_OSCH
566
	lds r20, chan4_vol
567
	lds r21, chan4_dut
568
	rcall generate
569
	sbrc r22, 3
570
	add RIGHT_BUF, r17
571
	
572
	reti
573
574
generate:
575
	clr r17
576
	cpi r18, 0b00
577
	breq gen_pulse
578
	cpi r18, 0b01
579
	breq gen_triangle
580
	cpi r18, 0b10
581
	breq gen_saw
582
	cpi r18, 0b11
583
	breq gen_noise
584
	ret
585
	
586
gen_pulse:
587
	cp r19, r21
588
	brlo return
589
	mov r17, r20
590
	lsr r17
591
	lsr r17
592
	ret
593
	
594
gen_triangle:
595
	mov r17, r19
596
	sbrc r19, 7
597
	com r17
598
	rjmp apply_volume
599
	ret
600
	
601
gen_saw:
602
	mov r17, r19
603
	lsr r17
604
	lsr r17
605
	rjmp apply_volume
606
	ret
607
	
608
gen_noise:
609
	clr r21
610
	clr r19
611
	sbrc NOISEH, 6
612
	ser r21
613
	sbrc NOISEL, 3
614
	ser r19
615
	eor r19, r21
616
	clr r21
617
	lsl NOISEH
618
	lsl NOISEL
619
	adc NOISEH, r21
620
	sbrc r19, 0
621
	inc NOISEL
622
	mov r17, NOISEL
623
	lsr r17
624
	rjmp apply_volume
625
	ret
626
	
627
apply_volume:
628
	sbrc r20, 7
629
	rjmp return
630
	lsr r17
631
	sbrc r20, 6
632
	rjmp return
633
	lsr r17
634
	sbrc r20, 5
635
	rjmp return
636
	lsr r17
637
	sbrc r20, 4
638
	rjmp return
639
	lsr r17
640
	sbrc r20, 3
641
	rjmp return
642
	lsr r17
643
	sbrc r20, 2
644
	rjmp return
645
	lsr r17
646
	sbrc r20, 1
647
	rjmp return
648
	lsr r17
649
return:
650
	ret
651
652
.dseg
653
chan1_vol: .byte 1
654
chan2_vol: .byte 1
655
chan3_vol: .byte 1
656
chan4_vol: .byte 1
657
658
chan1_dut: .byte 1
659
chan2_dut: .byte 1
660
chan3_dut: .byte 1
661
chan4_dut: .byte 1
662
663
fine_tune: .byte 2
664
waveform: .byte 1
665
enable: .byte 1
666
music_timer: .byte 2
667
tick_timer: .byte 1
668
669
tempo: .byte 1
670
speed: .byte 1
671
672
chan1_tvol: .byte 1
673
chan2_tvol: .byte 1
674
chan3_tvol: .byte 1
675
chan4_tvol: .byte 1
676
677
chan1_notes: .byte 2
678
chan2_notes: .byte 2
679
chan3_notes: .byte 2
680
chan4_notes: .byte 2
681
682
chan1_dir: .byte 1
683
chan2_dir: .byte 1
684
chan3_dir: .byte 1
685
chan4_dir: .byte 1