Mercurial > vba-clojure
view clojure/com/aurellem/run/music.clj @ 417:0b6624c1291c
made basic tone player.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 16 Apr 2012 14:08:56 -0500 |
parents | |
children | f211cd655ccb |
line wrap: on
line source
1 (ns com.aurellem.run.music2 (:use (com.aurellem.gb saves gb-driver util constants3 items vbm characters money4 rlm-assembly))5 (:use (com.aurellem.run util title save-corruption6 bootstrap-0 bootstrap-1))7 (:import [com.aurellem.gb.gb_driver SaveState]))10 (def music-base new-kernel)15 (defn store [n address]16 (flatten17 [0xF518 0xE520 0x3E21 n23 0x2124 (reverse (disect-bytes-2 address))26 0x7728 0xE129 0xF1]))31 (defn infinite-loop []32 [0x18 0xFE])36 (def divider-register 0xFF04)39 (defrecord Bit-Note [frequency volume duration duty])41 (defn clear-music-registers []42 (flatten43 [(store (Integer/parseInt "00000000" 2) 0xFF10)44 (store (Integer/parseInt "00000000" 2) 0xFF11)45 (store (Integer/parseInt "00000000" 2) 0xFF12)46 (store (Integer/parseInt "00000000" 2) 0xFF13)47 (store (Integer/parseInt "00000000" 2) 0xFF14)49 (store (Integer/parseInt "00000000" 2) 0xFF16) ;; pattern duty 00000050 (store (Integer/parseInt "00000000" 2) 0xFF17) ;; volume 000051 (store (Integer/parseInt "00000000" 2) 0xFF18) ;; frequency-low52 (store (Integer/parseInt "00000000" 2) 0xFF19) ;; 00000 frequency-high54 (store (Integer/parseInt "00000000" 2) 0xFF1A)55 (store (Integer/parseInt "00000000" 2) 0xFF1B)56 (store (Integer/parseInt "00000000" 2) 0xFF1C)57 (store (Integer/parseInt "00000000" 2) 0xFF1D)58 (store (Integer/parseInt "00000000" 2) 0xFF1E)60 (store (Integer/parseInt "00000000" 2) 0xFF20)61 (store (Integer/parseInt "00000000" 2) 0xFF21)62 (store (Integer/parseInt "00000000" 2) 0xFF22)63 (store (Integer/parseInt "00000000" 2) 0xFF23)]))65 (defn play-note66 "Play the note referenced by HL in the appropiate channel.67 Leaves desired-duration in A."68 []69 [0x2A ;; load volume/frequency-high info70 0xF5 ;; push A71 0xE672 (Integer/parseInt "11110000" 2) ;; volume mask73 0xE074 0x17 ;; set volume75 0xF1 ;; pop A76 0xE677 (Integer/parseInt "00000111" 2) ;; frequency-high mask78 0xE079 0x19 ;; set frequency-high81 0x2A ;; load frequency low-bits82 0xE083 0x18 ;; set frequency-low-bits85 0x7E ;; load duration86 ;;0x2B ;;87 ;;0x2B88 ]) ;; HL-2 -> HL90 (defn music-step []91 (flatten92 [(play-note)93 0xF5 ;; push A94 0xF095 0x05 ;; load current ticks96 0x90 ;; B holds previous sub-ticks, subtract it from A97 ;; if A-B caused a carry, then (B > A) is true, and98 ;; A = current-sub-tics, B = previous-sub-ticks, so99 ;; current-sub-ticks < previous-sub-ticks, which means that the100 ;; timer counter HAS overflowed.101 0x30 ;; increment C only if last result caused carry102 0x01103 0x00;;0x0C105 0x47 ;; update sub-ticks (A->B)107 0xF1 ;; pop AF, now A contains desired-ticks109 0xB9 ;; compare with current ticks111 ;; if desired-ticks = current ticks112 ;; go to next note ; set current set ticks to 0.114 0x20115 0x05117 0x23118 0x23119 0x23 ;; HL + 3 -> HL121 0x0E122 0x00])) ;; 0->C (current-ticks)124 (defn music-kernel []125 (flatten126 [(clear-music-registers)127 0x21128 0x00129 0xD0 ;; set HL to 0xD000 == music-start130 0x0E131 0x00 ;; 0->C132 0x06133 0x00 ;; 0->B135 0x3E136 0x00137 0xE0138 0x06 ;; set TMA to 0140 0x3E141 (Integer/parseInt "00000111" 2)142 0xE0143 0x07 ;; set TAC to 16384 Hz145 (music-step)146 0x18147 (->signed-8-bit (+ (- (count (music-step)))148 -2))]))151 (defn play-music [steps music-bytes]152 (let [program-target 0xC000153 music-target 0xD000]154 (-> (set-memory-range (second (music-base))155 program-target (music-kernel))156 (set-memory-range music-target music-bytes)157 (PC! program-target))))160 (defn test-note [music-bytes]161 (-> (set-memory-range (second (music-base))162 0xC000 (concat (clear-music-registers)163 (play-note)164 (infinite-loop)))165 (set-memory-range 0xD000 music-bytes)166 (PC! 0xC000)167 (HL! 0xD000)168 ))171 (defn run-program172 ([program] (run-program program 90))173 ([program steps]174 (let [target 0xC000]175 (-> (set-memory-range (second (music-base))176 target program)177 (PC! target)))))