changeset 377:1f14c1b8af7e

working on main bootstrap program
author Robert McIntyre <rlm@mit.edu>
date Wed, 11 Apr 2012 10:47:27 -0500
parents 7c89fe478de4
children 5c4a30521d09
files clojure/com/aurellem/exp/item_bridge.clj clojure/com/aurellem/gb/constants.clj clojure/com/aurellem/gb/dylan_assembly.clj clojure/com/aurellem/gb/rlm_assembly.clj clojure/com/aurellem/gb/util.clj clojure/com/aurellem/run/bootstrap_1.clj
diffstat 6 files changed, 217 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/exp/item_bridge.clj	Wed Apr 11 09:14:51 2012 -0500
     1.2 +++ b/clojure/com/aurellem/exp/item_bridge.clj	Wed Apr 11 10:47:27 2012 -0500
     1.3 @@ -41,30 +41,6 @@
     1.4  
     1.5  ;; (almost-broken 20) more or less works
     1.6  
     1.7 -(defn capture-program-counter
     1.8 -  "records the program counter for each tick"
     1.9 -  [^SaveState state ticks]
    1.10 -  (let [i (atom 0)]
    1.11 -    (reduce (fn [[program-counters state] _]
    1.12 -              (println (swap! i inc))
    1.13 -               [(conj program-counters (PC state))
    1.14 -                (tick state)])
    1.15 -              [[] state]
    1.16 -              (range ticks))))
    1.17 -
    1.18 -
    1.19 -(defn capture-program-counter
    1.20 -  [^SaveState state ticks]
    1.21 -  (tick state)
    1.22 -  
    1.23 -  (loop [i 0
    1.24 -         pcs []]
    1.25 -    (if (= i ticks)
    1.26 -      (filter (partial < 0x2000)(sort (set pcs)))
    1.27 -      (do 
    1.28 -        (com.aurellem.gb.Gb/tick)
    1.29 -        (recur (inc i)
    1.30 -               (conj pcs (first (registers))))))))
    1.31  
    1.32  (defn loop-program []
    1.33    [0x00     ;0xD31D  ;; disable-interrupts
     2.1 --- a/clojure/com/aurellem/gb/constants.clj	Wed Apr 11 09:14:51 2012 -0500
     2.2 +++ b/clojure/com/aurellem/gb/constants.clj	Wed Apr 11 10:47:27 2012 -0500
     2.3 @@ -9,4 +9,6 @@
     2.4  (def pokemon-record-begin 0xD162)
     2.5  (def pokemon-record-end 0xD2F5)
     2.6  
     2.7 -(def D-memory-end 0xD41B)
     2.8 \ No newline at end of file
     2.9 +(def D-memory-end 0xD41B)
    2.10 +
    2.11 +(def pokemon-list-start 0xD162)
    2.12 \ No newline at end of file
     3.1 --- a/clojure/com/aurellem/gb/dylan_assembly.clj	Wed Apr 11 09:14:51 2012 -0500
     3.2 +++ b/clojure/com/aurellem/gb/dylan_assembly.clj	Wed Apr 11 10:47:27 2012 -0500
     3.3 @@ -1,7 +1,7 @@
     3.4  (ns com.aurellem.gb.dylan-assembly
     3.5    "A much more compact version of write-memory-assembly"
     3.6    {:author "Dylan Holmes"}
     3.7 -  (:use (com.aurellem.gb gb-driver assembly util))
     3.8 +  (:use (com.aurellem.gb gb-driver assembly util vbm))
     3.9    (:import [com.aurellem.gb.gb_driver SaveState]))
    3.10  
    3.11  ;; Specs for main bootstrap program
    3.12 @@ -231,24 +231,65 @@
    3.13        (IE! 0)
    3.14        (inject-item-assembly (write-memory-assembly-compact))))
    3.15  
    3.16 -(defn drive-compact []
    3.17 -  (-> (write-mem-compact)
    3.18 -      (#(do (println "memory from 0xC00F to 0xC01F:"
    3.19 -                     (subvec (vec (memory %)) 0xC00F 0xC01F)) %))
    3.20 -      (step [])                       ; make sure it can handle blanks
    3.21 -      (step [])                       ; at the beginning.
    3.22 -      (step [])                      
    3.23 -      (step [:start])                 ; 
    3.24 -      (step [:select])
    3.25 -      (step [:u :d])
    3.26 -      (step [:a :b :start :select])
    3.27 -      (step [:a])
    3.28 -      (step [:b])
    3.29 -      (step [:a :b])
    3.30 -      (step [:select])
    3.31 -      (step [])
    3.32 -      (step [])
    3.33 -      (step [])
    3.34 -      (#(do (println "memory from 0xC00F to 0xC01F:"
    3.35 -                     (subvec (vec (memory %)) 0xC00F 0xC01F)) %))))
    3.36 +(defn test-write-bytes-mode []
    3.37 +  (let [target-address 0xD135
    3.38 +        [target-high target-low] (disect-bytes-2 target-address)
    3.39 +        assembly [0xF3 0x18 0xFE 0x12]
    3.40 +        get-mem-region  #(subvec (vec (memory %))
    3.41 +                                 target-address (+ target-address 20))
    3.42 +        before (write-mem-compact)
    3.43 +        after
    3.44 +        (-> before
    3.45 +            (step [])                       ; make sure it can handle blanks
    3.46 +            (step [])                       ; at the beginning.
    3.47 +            (step [])                      
    3.48 +            (step [:start])                 ; select WRITE-BYTES mode
    3.49 +            (step (buttons 4))              ; write 4 bytes
    3.50 +            (step (buttons target-high))
    3.51 +            (step (buttons target-low))
    3.52 +            (step (buttons (nth assembly 0)))
    3.53 +            (step (buttons (nth assembly 1)))
    3.54 +            (step (buttons (nth assembly 2)))
    3.55 +            (step (buttons (nth assembly 3)))
    3.56 +            (step [])
    3.57 +            (step [])
    3.58 +            (step []))]
    3.59 +            (println "before :" (get-mem-region before))
    3.60 +            (println "after  :" (get-mem-region after))
    3.61 +            (assert (= assembly (take 4 (get-mem-region after))))
    3.62 +    after))
    3.63  
    3.64 +(defn test-jump-mode []
    3.65 +  (let [target-address 0xC01F
    3.66 +        [target-high target-low] (disect-bytes-2 target-address)
    3.67 +        post-jump
    3.68 +        (-> (test-write-bytes-mode)
    3.69 +            (step [])
    3.70 +            (step [])
    3.71 +            (step [])
    3.72 +            (step (buttons 0xFF))           ; Select JUMP mode.
    3.73 +            (step (buttons target-high))
    3.74 +            (step (buttons target-low)))
    3.75 +        program-counters
    3.76 +        (capture-program-counter 
    3.77 +         post-jump
    3.78 +         10000)]
    3.79 +    (println program-counters)
    3.80 +    (assert (contains? (set program-counters) target-address))
    3.81 +    post-jump))
    3.82 +
    3.83 +
    3.84 +(defn test-loop []
    3.85 +  (contains?
    3.86 +   (set
    3.87 +    (capture-program-counter
    3.88 +     (-> (mid-game)
    3.89 +         ;;      (IE! 0)
    3.90 +         (set-memory-range 0xD135 [0xF3 0x18 0xFE])
    3.91 +         (PC! 0xD135)) 10000))
    3.92 +    0xD136))
    3.93 +     
    3.94 +      
    3.95 +
    3.96 +                
    3.97 +  
    3.98 \ No newline at end of file
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/clojure/com/aurellem/gb/rlm_assembly.clj	Wed Apr 11 10:47:27 2012 -0500
     4.3 @@ -0,0 +1,122 @@
     4.4 +(ns com.aurellem.gb.rlm-assembly
     4.5 +  "Version of main bootstrap program that is valid output for the
     4.6 +   item-writer program."
     4.7 +  (:use (com.aurellem.gb gb-driver assembly util vbm constants))
     4.8 +  (:use (com.aurellem.run bootstrap-1))
     4.9 +  (:import [com.aurellem.gb.gb_driver SaveState]))
    4.10 +
    4.11 +;; Specs for Main Bootstrap Program
    4.12 +
    4.13 +;; Number-Input
    4.14 +;; Number input works using all eight buttons to
    4.15 +;;   spell out an 8 bit number.  The order of buttons is
    4.16 +;;   [:d :u :l :r :start :select :b :a]  -->  11111111
    4.17 +;;   [      :l    :start            :a]  -->  00101001
    4.18 +
    4.19 +;;; MODE-SELECT
    4.20 +;;   The bootstrap program starts in MODE-SELECT mode.
    4.21 +;;   MODE-SELECT transitions to one of three modes depending
    4.22 +;;   on which buttons are pressed:
    4.23 +;;       0   (no-buttons)  :  MODE-SELECT
    4.24 +;;       8   [:start]      :  WRITE-BYTES
    4.25 +;;    0xFF   (all-buttons) :  JUMP
    4.26 +
    4.27 +;;; WRITE-BYTES
    4.28 +
    4.29 +;;   WRITE-BYTES mode writes sequences of arbitray values to
    4.30 +;;   arbitray memory locations. It expects you to enter a
    4.31 +;;   header of three bytes describing what to write:
    4.32 +
    4.33 +;;    Byte 0  : Number of Bytes to Write
    4.34 +;;    Byte 1  : Start Address High Byte
    4.35 +;;    Byte 1  : Start Address Low  Byte
    4.36 +
    4.37 +;;   Then, you enter the number of bytes specified in Byte 0
    4.38 +;;   they are written to the start address in
    4.39 +;;   sequence. After the last byte is written control
    4.40 +;;   returns to MODE-SELECT mode.
    4.41 +
    4.42 +;;   Example: to write the sequence [1 2 3 4] starting at
    4.43 +;;   address 0xC01F enter
    4.44 +;;    Byte 0  : 4 (will write four bytes)
    4.45 +;;    Byte 1  : 0xC0  (high byte of 0xC01F)
    4.46 +;;    Byte 2  : 0x1F  (low  byte of 0xC01F)
    4.47 +;;    Byte 3  : 1 (write 1 to 0xC01F)
    4.48 +;;    Byte 4  : 2 (write 2 to 0xC020)
    4.49 +;;    Byte 5  : 3 (write 3 to 0xC021)
    4.50 +;;    Byte 6  : 4 (write 4 to 0xC022)
    4.51 +
    4.52 +;;; JUMP 
    4.53 +;;   JUMP mode jumps program control to any arbitray
    4.54 +;;   location. It expects you to enter two bytes which
    4.55 +;;   correspond to the high and low bytes of the memory
    4.56 +;;   address to which you want to jump.
    4.57 +;;    Byte 0  : Jump Address High Byte
    4.58 +;;    Byte 1  : Jump Address Low  Byte
    4.59 +
    4.60 +;;   Example: to jump to address 0x1234 enter
    4.61 +;;    Byte 0  : 0x12 (high byte of 0x1234)
    4.62 +;;    Byte 1  : 0x34 (low  byte of 0x1234)
    4.63 +
    4.64 +
    4.65 +
    4.66 +(defn main-bootstrap-program [start-address]
    4.67 +  (let [[start-high start-low] (disect-bytes-2 start-address)]
    4.68 +    [0xF3 0x18 0xFE]))
    4.69 +
    4.70 +;;;;;; TESTS ;;;;;;
    4.71 +
    4.72 +(defn bootstrap-base []
    4.73 +  (let [program (main-bootstrap-program pokemon-list-start)]
    4.74 +    ;; make sure program is valid output for item-writer
    4.75 +    (bootstrap-pattern program)
    4.76 +    (-> (tick (mid-game))
    4.77 +        (set-memory-range pokemon-list-start program)
    4.78 +        (PC! pokemon-list-start))))
    4.79 +
    4.80 +(defn test-write-bytes-mode []
    4.81 +  (let [target-address 0xC00F
    4.82 +        [target-high target-low] (disect-bytes-2 target-address)
    4.83 +        assembly [0xF3 0x18 0xFE 0x12]
    4.84 +        get-mem-region  #(subvec (vec (memory %))
    4.85 +                                 target-address (+ target-address 20))
    4.86 +        before (bootstrap-base)
    4.87 +        after
    4.88 +        (-> before
    4.89 +            (step [])                       ; make sure it can handle blanks
    4.90 +            (step [])                       ; at the beginning.
    4.91 +            (step [])                      
    4.92 +            (step [:start])                 ; select WRITE-BYTES mode
    4.93 +            (step (buttons 4))              ; write 4 bytes
    4.94 +            (step (buttons target-high))
    4.95 +            (step (buttons target-low))
    4.96 +            (step (buttons (nth assembly 0)))
    4.97 +            (step (buttons (nth assembly 1)))
    4.98 +            (step (buttons (nth assembly 2)))
    4.99 +            (step (buttons (nth assembly 3)))
   4.100 +            (step [])
   4.101 +            (step [])
   4.102 +            (step []))]
   4.103 +            (println "before :" (get-mem-region before))
   4.104 +            (println "after  :" (get-mem-region after))
   4.105 +            (assert (= assembly (take 4 (get-mem-region after))))
   4.106 +    after))
   4.107 +
   4.108 +(defn test-jump-mode []
   4.109 +  (let [target-address 0xC00F
   4.110 +        [target-high target-low] (disect-bytes-2 target-address)
   4.111 +        post-jump
   4.112 +        (-> (test-write-bytes-mode)
   4.113 +            (step [])
   4.114 +            (step [])
   4.115 +            (step [])
   4.116 +            (step (buttons 0xFF))           ; Select JUMP mode.
   4.117 +            (step (buttons target-high))
   4.118 +            (step (buttons target-low)))
   4.119 +        program-counters
   4.120 +        (capture-program-counter 
   4.121 +         post-jump
   4.122 +         10000)]
   4.123 +    (println program-counters)
   4.124 +    (assert (contains? (set program-counters) target-address))
   4.125 +    post-jump))
     5.1 --- a/clojure/com/aurellem/gb/util.clj	Wed Apr 11 09:14:51 2012 -0500
     5.2 +++ b/clojure/com/aurellem/gb/util.clj	Wed Apr 11 10:47:27 2012 -0500
     5.3 @@ -252,4 +252,31 @@
     5.4      (if (bit-test n 7)
     5.5        (- lower-seven 128)
     5.6        lower-seven)))
     5.7 -  
     5.8 \ No newline at end of file
     5.9 +
    5.10 +
    5.11 +(defn capture-program-counter
    5.12 +  "records the program counter for each tick"
    5.13 +  [^SaveState state ticks]
    5.14 +  (let [i (atom 0)]
    5.15 +    (reduce (fn [[program-counters state] _]
    5.16 +              (swap! i inc)
    5.17 +              (if (= (rem @i 1000) 0) (println @i))
    5.18 +               [(conj program-counters (PC state))
    5.19 +                (tick state)])
    5.20 +              [[] state]
    5.21 +              (range ticks))))
    5.22 +
    5.23 +(defn capture-program-counter
    5.24 +  "Records the program counter for each tick"
    5.25 +  [^SaveState state ticks]
    5.26 +  (tick state)
    5.27 +  
    5.28 +  (loop [i 0
    5.29 +         pcs []]
    5.30 +    (if (= i ticks)
    5.31 +      (filter (partial < 0x2000)(sort (set pcs)))
    5.32 +      (do 
    5.33 +        (com.aurellem.gb.Gb/tick)
    5.34 +        (recur (inc i)
    5.35 +               (conj pcs (first (registers))))))))
    5.36 +
     6.1 --- a/clojure/com/aurellem/run/bootstrap_1.clj	Wed Apr 11 09:14:51 2012 -0500
     6.2 +++ b/clojure/com/aurellem/run/bootstrap_1.clj	Wed Apr 11 10:47:27 2012 -0500
     6.3 @@ -1,5 +1,5 @@
     6.4  (ns com.aurellem.run.bootstrap-1
     6.5 -  (:use (com.aurellem.gb saves gb-driver util
     6.6 +  (:use (com.aurellem.gb saves gb-driver util constants
     6.7                           items vbm characters money))
     6.8    (:use (com.aurellem.run util title save-corruption bootstrap-0))
     6.9    (:use (com.aurellem.exp item-bridge))
    6.10 @@ -8,7 +8,7 @@
    6.11  (defn pc-item-writer-program
    6.12    []
    6.13    (let [limit 201
    6.14 -        [target-high target-low] (disect-bytes-2 0xD162)]
    6.15 +        [target-high target-low] (disect-bytes-2 pokemon-list-start)]
    6.16      (flatten
    6.17       [[0x00  ;; (item-hack) set increment stack pointer no-op
    6.18         0x1E  ;; load limit into E