Mercurial > vba-clojure
changeset 417:0b6624c1291c
made basic tone player.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Mon, 16 Apr 2012 14:08:56 -0500 |
parents | 21b8b3350b20 |
children | f211cd655ccb |
files | .hgignore clojure/com/aurellem/gb/util.clj clojure/com/aurellem/run/bootstrap_1.clj clojure/com/aurellem/run/music.clj moves/new-kernel.vbm save-states/new-kernel.sav |
diffstat | 6 files changed, 199 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/.hgignore Sat Apr 14 05:41:55 2012 -0500 1.2 +++ b/.hgignore Mon Apr 16 14:08:56 2012 -0500 1.3 @@ -15,3 +15,4 @@ 1.4 java/dist/* 1.5 java/headers/* 1.6 java/.ant-targets-build.xml 1.7 +html/*
2.1 --- a/clojure/com/aurellem/gb/util.clj Sat Apr 14 05:41:55 2012 -0500 2.2 +++ b/clojure/com/aurellem/gb/util.clj Mon Apr 16 14:08:56 2012 -0500 2.3 @@ -3,8 +3,10 @@ 2.4 (:import java.io.File) 2.5 (:import [com.aurellem.gb.gb_driver SaveState])) 2.6 2.7 -(defn A [state] 2.8 - (bit-shift-right (bit-and 0x0000FF00 (AF state)) 8)) 2.9 +(defn A 2.10 + ([state] 2.11 + (bit-shift-right (bit-and 0x0000FF00 (AF state)) 8)) 2.12 + ([] (A @current-state))) 2.13 2.14 (defn B [state] 2.15 (bit-shift-right (bit-and 0x0000FF00 (BC state)) 8)) 2.16 @@ -112,8 +114,12 @@ 2.17 ([] (print-op @current-state))) 2.18 2.19 (defn d-tick 2.20 - ([state] 2.21 - (-> state print-pc print-op tick))) 2.22 + ([] (d-tick 1)) 2.23 + ([n] (d-tick n @current-state)) 2.24 + ([n state] 2.25 + (reduce (fn [state _] 2.26 + (-> state print-pc print-op tick)) 2.27 + state (range n)))) 2.28 2.29 (defn print-interrupt 2.30 [^SaveState state]
3.1 --- a/clojure/com/aurellem/run/bootstrap_1.clj Sat Apr 14 05:41:55 2012 -0500 3.2 +++ b/clojure/com/aurellem/run/bootstrap_1.clj Mon Apr 16 14:08:56 2012 -0500 3.3 @@ -858,6 +858,13 @@ 3.4 (transfer-control target) 3.5 (do-nothing 1))))) 3.6 3.7 +(defn gen-new-kernel-checkpoint! [] 3.8 + (write-script! (do-nothing 10 (relocate-main-bootstrap)) 3.9 + "new-kernel")) 3.10 + 3.11 +(defn new-kernel [] (read-script "new-kernel")) 3.12 + 3.13 + 3.14 (def mid-game-data 3.15 (subvec (vec (memory (mid-game))) 3.16 pokemon-list-start 3.17 @@ -865,7 +872,7 @@ 3.18 3.19 (def mid-game-map-address 0x46BC) 3.20 3.21 -(defn set-mid-game-data 3.22 +(defn-memo set-mid-game-data 3.23 ([] (set-mid-game-data (relocate-main-bootstrap))) 3.24 ([script] 3.25 (->> script 3.26 @@ -888,7 +895,7 @@ 3.27 pokemon-list-start 3.28 (+ pokemon-list-start 500)))) 3.29 3.30 -(defn return-to-pokemon-kernel 3.31 +(defn-memo return-to-pokemon-kernel 3.32 ([] (return-to-pokemon-kernel (set-mid-game-data))) 3.33 ([script] 3.34 (let [scratch (+ 200 pokemon-box-1-address)
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/clojure/com/aurellem/run/music.clj Mon Apr 16 14:08:56 2012 -0500 4.3 @@ -0,0 +1,179 @@ 4.4 +(ns com.aurellem.run.music 4.5 + (:use (com.aurellem.gb saves gb-driver util constants 4.6 + items vbm characters money 4.7 + rlm-assembly)) 4.8 + (:use (com.aurellem.run util title save-corruption 4.9 + bootstrap-0 bootstrap-1)) 4.10 + (:import [com.aurellem.gb.gb_driver SaveState])) 4.11 + 4.12 + 4.13 +(def music-base new-kernel) 4.14 + 4.15 + 4.16 + 4.17 + 4.18 +(defn store [n address] 4.19 + (flatten 4.20 + [0xF5 4.21 + 0xE5 4.22 + 4.23 + 0x3E 4.24 + n 4.25 + 4.26 + 0x21 4.27 + (reverse (disect-bytes-2 address)) 4.28 + 4.29 + 0x77 4.30 + 4.31 + 0xE1 4.32 + 0xF1])) 4.33 + 4.34 +(defn infinite-loop [] 4.35 + [0x18 0xFE]) 4.36 + 4.37 + 4.38 + 4.39 +(def divider-register 0xFF04) 4.40 + 4.41 + 4.42 +(defrecord Bit-Note [frequency volume duration duty]) 4.43 + 4.44 +(defn clear-music-registers [] 4.45 + (flatten 4.46 + [(store (Integer/parseInt "00000000" 2) 0xFF10) 4.47 + (store (Integer/parseInt "00000000" 2) 0xFF11) 4.48 + (store (Integer/parseInt "00000000" 2) 0xFF12) 4.49 + (store (Integer/parseInt "00000000" 2) 0xFF13) 4.50 + (store (Integer/parseInt "00000000" 2) 0xFF14) 4.51 + 4.52 + (store (Integer/parseInt "00000000" 2) 0xFF16) ;; pattern duty 000000 4.53 + (store (Integer/parseInt "00000000" 2) 0xFF17) ;; volume 0000 4.54 + (store (Integer/parseInt "00000000" 2) 0xFF18) ;; frequency-low 4.55 + (store (Integer/parseInt "00000000" 2) 0xFF19) ;; 00000 frequency-high 4.56 + 4.57 + (store (Integer/parseInt "00000000" 2) 0xFF1A) 4.58 + (store (Integer/parseInt "00000000" 2) 0xFF1B) 4.59 + (store (Integer/parseInt "00000000" 2) 0xFF1C) 4.60 + (store (Integer/parseInt "00000000" 2) 0xFF1D) 4.61 + (store (Integer/parseInt "00000000" 2) 0xFF1E) 4.62 + 4.63 + (store (Integer/parseInt "00000000" 2) 0xFF20) 4.64 + (store (Integer/parseInt "00000000" 2) 0xFF21) 4.65 + (store (Integer/parseInt "00000000" 2) 0xFF22) 4.66 + (store (Integer/parseInt "00000000" 2) 0xFF23)])) 4.67 + 4.68 +(defn play-note 4.69 + "Play the note referenced by HL in the appropiate channel. 4.70 + Leaves desired-duration in A." 4.71 + [] 4.72 + [0x2A ;; load volume/frequency-high info 4.73 + 0xF5 ;; push A 4.74 + 0xE6 4.75 + (Integer/parseInt "11110000" 2) ;; volume mask 4.76 + 0xE0 4.77 + 0x17 ;; set volume 4.78 + 0xF1 ;; pop A 4.79 + 0xE6 4.80 + (Integer/parseInt "00000111" 2) ;; frequency-high mask 4.81 + 0xE0 4.82 + 0x19 ;; set frequency-high 4.83 + 4.84 + 0x2A ;; load frequency low-bits 4.85 + 0xE0 4.86 + 0x18 ;; set frequency-low-bits 4.87 + 4.88 + 0x7E ;; load duration 4.89 + ;;0x2B ;; 4.90 + ;;0x2B 4.91 + ]) ;; HL-2 -> HL 4.92 + 4.93 +(defn music-step [] 4.94 + (flatten 4.95 + [(play-note) 4.96 + 0xF5 ;; push A 4.97 + 0xF0 4.98 + 0x05 ;; load current ticks 4.99 + 0x90 ;; B holds previous sub-ticks, subtract it from A 4.100 + ;; if A-B caused a carry, then (B > A) is true, and 4.101 + ;; A = current-sub-tics, B = previous-sub-ticks, so 4.102 + ;; current-sub-ticks < previous-sub-ticks, which means that the 4.103 + ;; timer counter HAS overflowed. 4.104 + 0x30 ;; increment C only if last result caused carry 4.105 + 0x01 4.106 + 0x00;;0x0C 4.107 + 4.108 + 0x47 ;; update sub-ticks (A->B) 4.109 + 4.110 + 0xF1 ;; pop AF, now A contains desired-ticks 4.111 + 4.112 + 0xB9 ;; compare with current ticks 4.113 + 4.114 + ;; if desired-ticks = current ticks 4.115 + ;; go to next note ; set current set ticks to 0. 4.116 + 4.117 + 0x20 4.118 + 0x05 4.119 + 4.120 + 0x23 4.121 + 0x23 4.122 + 0x23 ;; HL + 3 -> HL 4.123 + 4.124 + 0x0E 4.125 + 0x00])) ;; 0->C (current-ticks) 4.126 + 4.127 +(defn music-kernel [] 4.128 + (flatten 4.129 + [(clear-music-registers) 4.130 + 0x21 4.131 + 0x00 4.132 + 0xD0 ;; set HL to 0xD000 == music-start 4.133 + 0x0E 4.134 + 0x00 ;; 0->C 4.135 + 0x06 4.136 + 0x00 ;; 0->B 4.137 + 4.138 + 0x3E 4.139 + 0x00 4.140 + 0xE0 4.141 + 0x06 ;; set TMA to 0 4.142 + 4.143 + 0x3E 4.144 + (Integer/parseInt "00000111" 2) 4.145 + 0xE0 4.146 + 0x07 ;; set TAC to 16384 Hz 4.147 + 4.148 + (music-step) 4.149 + 0x18 4.150 + (->signed-8-bit (+ (- (count (music-step))) 4.151 + -2))])) 4.152 + 4.153 + 4.154 +(defn play-music [steps music-bytes] 4.155 + (let [program-target 0xC000 4.156 + music-target 0xD000] 4.157 + (-> (set-memory-range (second (music-base)) 4.158 + program-target (music-kernel)) 4.159 + (set-memory-range music-target music-bytes) 4.160 + (PC! program-target)))) 4.161 + 4.162 + 4.163 +(defn test-note [music-bytes] 4.164 + (-> (set-memory-range (second (music-base)) 4.165 + 0xC000 (concat (clear-music-registers) 4.166 + (play-note) 4.167 + (infinite-loop))) 4.168 + (set-memory-range 0xD000 music-bytes) 4.169 + (PC! 0xC000) 4.170 + (HL! 0xD000) 4.171 + )) 4.172 + 4.173 + 4.174 +(defn run-program 4.175 + ([program] (run-program program 90)) 4.176 + ([program steps] 4.177 + (let [target 0xC000] 4.178 + (-> (set-memory-range (second (music-base)) 4.179 + target program) 4.180 + (PC! target))))) 4.181 + 4.182 +
5.1 Binary file moves/new-kernel.vbm has changed
6.1 Binary file save-states/new-kernel.sav has changed