MegaLoler

Untitled

Dec 18th, 2012
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. .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. out ddrd, r16
  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, 0x00
  146. mov NOISEH, r16
  147.  
  148. ldi r16, 0b0000
  149. sts enable, r16
  150.  
  151. ldi r16, 0x08
  152. sts tempo, r16
  153. ldi r16, 0x06
  154. sts speed, r16
  155.  
  156. ldi r16, 0x80
  157. sts chan1_vol, r16
  158. sts chan2_vol, r16
  159. sts chan3_vol, r16
  160. sts chan4_vol, r16
  161.  
  162. ldi r16, 0x80
  163. sts chan1_dut, r16
  164. sts chan2_dut, r16
  165. sts chan3_dut, r16
  166. sts chan4_dut, r16
  167.  
  168. ldi r16, 0x45
  169. sts chan1_notes, r16
  170. ldi r16, 0x00
  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. 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
Advertisement
Add Comment
Please, Sign In to add comment