# HG changeset patch
# User Robert McIntyre <rlm@mit.edu>
# Date 1334662603 18000
# Node ID b58a356f7cc266259745c0133878866fd22bf03b
# Parent  f211cd655ccbb9edabff778375d0ddeb3fa7980e# Parent  13165fb5852b343e27f35d1b2ce1abab214876de
merge.

diff -r 13165fb5852b -r b58a356f7cc2 .hgignore
--- a/.hgignore	Sat Apr 14 12:24:00 2012 -0500
+++ b/.hgignore	Tue Apr 17 06:36:43 2012 -0500
@@ -15,3 +15,4 @@
 java/dist/*
 java/headers/*
 java/.ant-targets-build.xml
+html/*
diff -r 13165fb5852b -r b58a356f7cc2 clojure/com/aurellem/gb/util.clj
--- a/clojure/com/aurellem/gb/util.clj	Sat Apr 14 12:24:00 2012 -0500
+++ b/clojure/com/aurellem/gb/util.clj	Tue Apr 17 06:36:43 2012 -0500
@@ -3,8 +3,10 @@
   (:import java.io.File)
   (:import [com.aurellem.gb.gb_driver SaveState]))
 
-(defn A [state]
-  (bit-shift-right (bit-and 0x0000FF00 (AF state)) 8))
+(defn A
+  ([state]
+     (bit-shift-right (bit-and 0x0000FF00 (AF state)) 8))
+  ([] (A @current-state)))
 
 (defn B [state]
   (bit-shift-right (bit-and 0x0000FF00 (BC state)) 8))
@@ -112,8 +114,12 @@
   ([] (print-op @current-state)))
 
 (defn d-tick
-  ([state]
-  (-> state print-pc print-op tick)))
+  ([] (d-tick 1))
+  ([n] (d-tick n @current-state))
+  ([n state]
+     (reduce (fn [state _]
+               (-> state print-pc print-op tick))
+             state (range n))))
 
 (defn print-interrupt
   [^SaveState state]
diff -r 13165fb5852b -r b58a356f7cc2 clojure/com/aurellem/run/bootstrap_1.clj
--- a/clojure/com/aurellem/run/bootstrap_1.clj	Sat Apr 14 12:24:00 2012 -0500
+++ b/clojure/com/aurellem/run/bootstrap_1.clj	Tue Apr 17 06:36:43 2012 -0500
@@ -858,6 +858,13 @@
             (transfer-control target)
             (do-nothing 1)))))
 
+(defn gen-new-kernel-checkpoint! []
+  (write-script! (do-nothing 10 (relocate-main-bootstrap))
+                 "new-kernel"))
+
+(defn new-kernel [] (read-script "new-kernel"))
+
+
 (def mid-game-data
   (subvec (vec (memory (mid-game)))
           pokemon-list-start
@@ -865,7 +872,7 @@
 
 (def mid-game-map-address 0x46BC)
 
-(defn set-mid-game-data
+(defn-memo set-mid-game-data
   ([] (set-mid-game-data (relocate-main-bootstrap)))
   ([script]
      (->> script
@@ -888,7 +895,7 @@
              pokemon-list-start
              (+ pokemon-list-start 500))))
 
-(defn return-to-pokemon-kernel
+(defn-memo return-to-pokemon-kernel
   ([] (return-to-pokemon-kernel (set-mid-game-data)))
   ([script]
      (let [scratch (+ 200 pokemon-box-1-address)
diff -r 13165fb5852b -r b58a356f7cc2 clojure/com/aurellem/run/music.clj
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clojure/com/aurellem/run/music.clj	Tue Apr 17 06:36:43 2012 -0500
@@ -0,0 +1,217 @@
+(ns com.aurellem.run.music
+  (:use (com.aurellem.gb saves gb-driver util constants
+                         items vbm characters money
+                         rlm-assembly))
+  (:use (com.aurellem.run util title save-corruption
+                          bootstrap-0 bootstrap-1))
+  (:import [com.aurellem.gb.gb_driver SaveState]))
+
+
+(def music-base new-kernel)
+
+
+
+
+(defn store [n address]
+  (flatten
+   [0xF5
+    0xE5
+    
+    0x3E
+    n
+    
+    0x21
+    (reverse (disect-bytes-2 address))
+
+    0x77
+    
+    0xE1
+    0xF1]))
+
+(defn infinite-loop []
+  [0x18 0xFE])
+
+
+
+(def divider-register 0xFF04)
+
+
+(defrecord Bit-Note [frequency volume duration duty])
+
+(defn clear-music-registers []
+  (flatten
+   [(store (Integer/parseInt "00000000" 2) 0xFF10)
+    (store (Integer/parseInt "00000000" 2) 0xFF11)
+    (store (Integer/parseInt "00000000" 2) 0xFF12)
+    (store (Integer/parseInt "00000000" 2) 0xFF13)
+    (store (Integer/parseInt "00000000" 2) 0xFF14)
+
+    (store (Integer/parseInt "00000000" 2) 0xFF16) ;; pattern duty 000000
+    (store (Integer/parseInt "00000000" 2) 0xFF17) ;; volume 0000
+    (store (Integer/parseInt "00000000" 2) 0xFF18) ;; frequency-low
+    (store (Integer/parseInt "00000000" 2) 0xFF19) ;; 00000 frequency-high
+
+    (store (Integer/parseInt "00000000" 2) 0xFF1A)
+    (store (Integer/parseInt "00000000" 2) 0xFF1B)
+    (store (Integer/parseInt "00000000" 2) 0xFF1C)
+    (store (Integer/parseInt "00000000" 2) 0xFF1D)
+    (store (Integer/parseInt "00000000" 2) 0xFF1E)
+
+    (store (Integer/parseInt "00000000" 2) 0xFF20)
+    (store (Integer/parseInt "00000000" 2) 0xFF21)
+    (store (Integer/parseInt "00000000" 2) 0xFF22)
+    (store (Integer/parseInt "00000000" 2) 0xFF23)]))
+
+(defn play-note
+  "Play the note referenced by HL in the appropiate channel.
+   Leaves desired-duration in A."
+  []
+  [0x2A   ;; load volume/frequency-high info
+   0xF5   ;; push A
+   0xE6
+   (Integer/parseInt "11110000" 2) ;; volume mask
+   0xE0
+   0x17   ;; set volume
+   0xF1   ;; pop A
+   0xE6
+   (Integer/parseInt "00000111" 2) ;; frequency-high mask
+   0xE0   
+   0x19   ;; set frequency-high
+   
+   0x2A   ;; load frequency low-bits
+   0xE0
+   0x18   ;; set frequency-low-bits
+
+   0x7E   ;; load duration
+   0x2B   ;; 
+   0x2B   ;; HL-2 -> HL
+   ]) 
+
+(defn music-step []
+  (flatten
+   [(play-note)
+    0xF5 ;; push A
+    0xF0
+    0x05 ;; load current ticks
+    0xB8 ;; B holds previous sub-ticks, subtract it from A
+    ;; if A-B caused a carry, then (B > A) is true, and
+    ;; A = current-sub-tics, B = previous-sub-ticks, so
+    ;; current-sub-ticks < previous-sub-ticks, which means that the
+    ;; timer counter HAS overflowed.
+    0x30 ;; increment C only if last result caused carry
+    0x01
+    0x0C
+
+    0x47 ;; update sub-ticks (A->B)
+
+    0xF1 ;; pop AF, now A contains desired-ticks
+
+    0xB9 ;; compare with current ticks
+
+    ;; if desired-ticks = current ticks
+    ;;   go to next note ; set current set ticks to 0.
+
+    0x20
+    0x05
+
+    0x23
+    0x23
+    0x23 ;; HL + 3 -> HL
+    
+    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)
+
+    0x21
+    0x00
+    0xD0 ;; set HL to 0xD000 == music-start
+    0x0E
+    0x00 ;; 0->C
+    0x06
+    0x00 ;; 0->B
+
+    0x3E
+    0x01
+    0xE0
+    0x06 ;; set TMA to 0
+    
+    0x3E
+    (Integer/parseInt "00000111" 2)
+    0xE0
+    0x07 ;; set TAC to 16384 Hz and activate timer
+
+    0xF0
+    0x07
+    
+    (music-step)
+    0x18
+    (->signed-8-bit (+ (- (count (music-step)))
+                       -2))]))
+
+(def one-note
+  [0xA0 0x00 0xFF])
+
+(def many-notes
+  (flatten (repeat 10 one-note)))
+
+(def increasing-notes
+  [0xA0 0x00 0x55
+   0xA1 0x00 0x55
+   0xA2 0x00 0x55
+   0xA3 0x00 0x55
+   0xA4 0x00 0x55
+   0xA5 0x00 0x55
+   0xA6 0x00 0x55
+   0xA7 0x00 0x55])
+   
+(defn play-music [music-bytes]
+  (let [program-target 0xC000
+        music-target 0xD000]
+    (-> (set-memory-range (second (music-base))
+                          program-target (music-kernel))
+        (set-memory-range music-target music-bytes)
+        (PC! program-target))))
+
+
+(defn test-note [music-bytes]
+  (-> (set-memory-range (second (music-base))
+                        0xC000 (concat (clear-music-registers)
+                                       (play-note)
+                                       (infinite-loop)))
+      (set-memory-range 0xD000 music-bytes)
+      (PC! 0xC000)
+      (HL! 0xD000)
+      ))
+
+
+(defn run-program
+  ([program]
+     (let [target 0xC000]
+       (-> (set-memory-range (second (music-base))
+                             target program)
+           (PC! target)))))
+
+(defn trippy []
+  (run-moves (play-music many-notes ) (repeat 8000 [])))
+
diff -r 13165fb5852b -r b58a356f7cc2 moves/new-kernel.vbm
Binary file moves/new-kernel.vbm has changed
diff -r 13165fb5852b -r b58a356f7cc2 save-states/new-kernel.sav
Binary file save-states/new-kernel.sav has changed