Mercurial > vba-clojure
diff clojure/com/aurellem/gb/rlm_assembly.clj @ 377:1f14c1b8af7e
working on main bootstrap program
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 11 Apr 2012 10:47:27 -0500 |
parents | |
children | 5c4a30521d09 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/clojure/com/aurellem/gb/rlm_assembly.clj Wed Apr 11 10:47:27 2012 -0500 1.3 @@ -0,0 +1,122 @@ 1.4 +(ns com.aurellem.gb.rlm-assembly 1.5 + "Version of main bootstrap program that is valid output for the 1.6 + item-writer program." 1.7 + (:use (com.aurellem.gb gb-driver assembly util vbm constants)) 1.8 + (:use (com.aurellem.run bootstrap-1)) 1.9 + (:import [com.aurellem.gb.gb_driver SaveState])) 1.10 + 1.11 +;; Specs for Main Bootstrap Program 1.12 + 1.13 +;; Number-Input 1.14 +;; Number input works using all eight buttons to 1.15 +;; spell out an 8 bit number. The order of buttons is 1.16 +;; [:d :u :l :r :start :select :b :a] --> 11111111 1.17 +;; [ :l :start :a] --> 00101001 1.18 + 1.19 +;;; MODE-SELECT 1.20 +;; The bootstrap program starts in MODE-SELECT mode. 1.21 +;; MODE-SELECT transitions to one of three modes depending 1.22 +;; on which buttons are pressed: 1.23 +;; 0 (no-buttons) : MODE-SELECT 1.24 +;; 8 [:start] : WRITE-BYTES 1.25 +;; 0xFF (all-buttons) : JUMP 1.26 + 1.27 +;;; WRITE-BYTES 1.28 + 1.29 +;; WRITE-BYTES mode writes sequences of arbitray values to 1.30 +;; arbitray memory locations. It expects you to enter a 1.31 +;; header of three bytes describing what to write: 1.32 + 1.33 +;; Byte 0 : Number of Bytes to Write 1.34 +;; Byte 1 : Start Address High Byte 1.35 +;; Byte 1 : Start Address Low Byte 1.36 + 1.37 +;; Then, you enter the number of bytes specified in Byte 0 1.38 +;; they are written to the start address in 1.39 +;; sequence. After the last byte is written control 1.40 +;; returns to MODE-SELECT mode. 1.41 + 1.42 +;; Example: to write the sequence [1 2 3 4] starting at 1.43 +;; address 0xC01F enter 1.44 +;; Byte 0 : 4 (will write four bytes) 1.45 +;; Byte 1 : 0xC0 (high byte of 0xC01F) 1.46 +;; Byte 2 : 0x1F (low byte of 0xC01F) 1.47 +;; Byte 3 : 1 (write 1 to 0xC01F) 1.48 +;; Byte 4 : 2 (write 2 to 0xC020) 1.49 +;; Byte 5 : 3 (write 3 to 0xC021) 1.50 +;; Byte 6 : 4 (write 4 to 0xC022) 1.51 + 1.52 +;;; JUMP 1.53 +;; JUMP mode jumps program control to any arbitray 1.54 +;; location. It expects you to enter two bytes which 1.55 +;; correspond to the high and low bytes of the memory 1.56 +;; address to which you want to jump. 1.57 +;; Byte 0 : Jump Address High Byte 1.58 +;; Byte 1 : Jump Address Low Byte 1.59 + 1.60 +;; Example: to jump to address 0x1234 enter 1.61 +;; Byte 0 : 0x12 (high byte of 0x1234) 1.62 +;; Byte 1 : 0x34 (low byte of 0x1234) 1.63 + 1.64 + 1.65 + 1.66 +(defn main-bootstrap-program [start-address] 1.67 + (let [[start-high start-low] (disect-bytes-2 start-address)] 1.68 + [0xF3 0x18 0xFE])) 1.69 + 1.70 +;;;;;; TESTS ;;;;;; 1.71 + 1.72 +(defn bootstrap-base [] 1.73 + (let [program (main-bootstrap-program pokemon-list-start)] 1.74 + ;; make sure program is valid output for item-writer 1.75 + (bootstrap-pattern program) 1.76 + (-> (tick (mid-game)) 1.77 + (set-memory-range pokemon-list-start program) 1.78 + (PC! pokemon-list-start)))) 1.79 + 1.80 +(defn test-write-bytes-mode [] 1.81 + (let [target-address 0xC00F 1.82 + [target-high target-low] (disect-bytes-2 target-address) 1.83 + assembly [0xF3 0x18 0xFE 0x12] 1.84 + get-mem-region #(subvec (vec (memory %)) 1.85 + target-address (+ target-address 20)) 1.86 + before (bootstrap-base) 1.87 + after 1.88 + (-> before 1.89 + (step []) ; make sure it can handle blanks 1.90 + (step []) ; at the beginning. 1.91 + (step []) 1.92 + (step [:start]) ; select WRITE-BYTES mode 1.93 + (step (buttons 4)) ; write 4 bytes 1.94 + (step (buttons target-high)) 1.95 + (step (buttons target-low)) 1.96 + (step (buttons (nth assembly 0))) 1.97 + (step (buttons (nth assembly 1))) 1.98 + (step (buttons (nth assembly 2))) 1.99 + (step (buttons (nth assembly 3))) 1.100 + (step []) 1.101 + (step []) 1.102 + (step []))] 1.103 + (println "before :" (get-mem-region before)) 1.104 + (println "after :" (get-mem-region after)) 1.105 + (assert (= assembly (take 4 (get-mem-region after)))) 1.106 + after)) 1.107 + 1.108 +(defn test-jump-mode [] 1.109 + (let [target-address 0xC00F 1.110 + [target-high target-low] (disect-bytes-2 target-address) 1.111 + post-jump 1.112 + (-> (test-write-bytes-mode) 1.113 + (step []) 1.114 + (step []) 1.115 + (step []) 1.116 + (step (buttons 0xFF)) ; Select JUMP mode. 1.117 + (step (buttons target-high)) 1.118 + (step (buttons target-low))) 1.119 + program-counters 1.120 + (capture-program-counter 1.121 + post-jump 1.122 + 10000)] 1.123 + (println program-counters) 1.124 + (assert (contains? (set program-counters) target-address)) 1.125 + post-jump))