# HG changeset patch # User Robert McIntyre # Date 1335174355 18000 # Node ID 7bd806c4dbb608cca06d028a4bec0f232fa6ad99 # Parent 971bd1774eab957857beeed74c1067dcc745dd66 changed assembly to handle mini-midi messages of different lengths. diff -r 971bd1774eab -r 7bd806c4dbb6 clojure/com/aurellem/run/music.clj --- a/clojure/com/aurellem/run/music.clj Tue Apr 17 06:53:48 2012 -0500 +++ b/clojure/com/aurellem/run/music.clj Mon Apr 23 04:45:55 2012 -0500 @@ -62,6 +62,44 @@ (store (Integer/parseInt "00000000" 2) 0xFF22) (store (Integer/parseInt "00000000" 2) 0xFF23)])) + +;; mini-midi syntax + +;; codes +;; note-code == 0x00 +;; change-duty-code = 0x01 +;; silence-code = 0x02 + +;; silence format +;; 2 bytes +;; [silence-code (0x02)] +;; [duration-8-bits] + +;; note data format +;; 4 bytes +;; [note-code (0x00)] +;; [volume-4-bits 0 frequency-high-3-bits] +;; [frequengy-low-8-bits] +;; [duration-8-bits] + +;; change-duty-format +;; 2 bytes +;; [change-duty-code (0x01)] +;; [new-duty] + +(defn do-message + "Read the message which starts at the current value of HL and do + what it says. Duration is left in A, and HL is advanced + appropraitely." + [] + + ) + + + + + + (defn play-note "Play the note referenced by HL in the appropiate channel. Leaves desired-duration in A." @@ -82,14 +120,12 @@ 0xE0 0x18 ;; set frequency-low-bits - 0x7E ;; load duration - 0x2B ;; - 0x2B ;; HL-2 -> HL + 0x2A ;; load duration ]) (defn music-step [] (flatten - [(play-note) + [ 0xF5 ;; push A 0xF0 0x05 ;; load current ticks @@ -112,33 +148,13 @@ ;; go to next note ; set current set ticks to 0. 0x20 - 0x05 + (+ (count (play-note)) 2) - 0x23 - 0x23 - 0x23 ;; HL + 3 -> HL + (play-note) 0x0E 0x00])) ;; 0->C (current-ticks) -(defn test-timer [] - (flatten - [0x3E - 0x01 - 0xE0 - 0x06 ;; set TMA to 0 - - 0x3E - (Integer/parseInt "00000100" 2) - 0xE0 - 0x07 ;; set TAC to 16384 Hz and activate timer - - (repeat - 500 - [0xF0 - 0x05])])) - - (defn music-kernel [] (flatten [(clear-music-registers) @@ -161,9 +177,10 @@ 0xE0 0x07 ;; set TAC to 65536 Hz and activate timer - 0xF0 - 0x07 - + + 0xAF ;; initialiaze A to zero + + (music-step) 0x18 (->signed-8-bit (+ (- (count (music-step))) @@ -188,8 +205,59 @@ 0xA6 0x55 0xFF 0x00 0x00 0xFF ]) - - + +(defn frequency-code->frequency + [code] + (assert (<= 0 code 2047)) + (/ 131072 (- 2048 code))) + +(defn clamp [x low high] + (cond (> x high) high + (< x low) low + true x)) + +(defn frequency->frequency-code + [frequency] + (clamp + (Math/round + (float + (/ (- (* 2048 frequency) 131072) frequency))) + 0x00 2048)) + +(defn note-codes [frequency volume duration] + (assert (<= 0 volume 0xF)) + (assert (<= 0 duration 0xFF)) + (let [frequency-code + (frequency->frequency-code frequency) + volume&high-frequency + (+ (bit-shift-left volume 4) + (bit-shift-right frequency-code 8)) + low-frequency + (bit-and 0xFF frequency-code)] + [volume&high-frequency + low-frequency + duration])) + +(def C4 (partial note-codes 261.63)) +(def D4 (partial note-codes 293.66)) +(def E4 (partial note-codes 329.63)) +(def F4 (partial note-codes 349.23)) +(def G4 (partial note-codes 392)) +(def A4 (partial note-codes 440)) +(def B4 (partial note-codes 493.88)) +(def C5 (partial note-codes 523.3)) + +(def scale + (flatten + [(C4 0xF 0x40) + (D4 0xF 0x40) + (E4 0xF 0x40) + (F4 0xF 0x40) + (G4 0xF 0x40) + (A4 0xF 0x40) + (B4 0xF 0x40) + (C5 0xF 0x40)])) + (defn play-music [music-bytes] (let [program-target 0xC000 music-target 0xD000] @@ -220,3 +288,19 @@ (defn trippy [] (run-moves (play-music many-notes ) (repeat 8000 []))) +(defn test-timer [] + (flatten + [0x3E + 0x01 + 0xE0 + 0x06 ;; set TMA to 0 + + 0x3E + (Integer/parseInt "00000100" 2) + 0xE0 + 0x07 ;; set TAC to 16384 Hz and activate timer + + (repeat + 500 + [0xF0 + 0x05])]))