diff clojure/com/aurellem/run/bootstrap_1.clj @ 414:0162dd315814

moved asseitem-writer assembly to rlm-assembly.
author Robert McIntyre <rlm@mit.edu>
date Sat, 14 Apr 2012 03:22:10 -0500
parents 1f14c1b8af7e
children f2f1e0b8c1c7
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/run/bootstrap_1.clj	Sat Apr 14 01:32:49 2012 -0500
     1.2 +++ b/clojure/com/aurellem/run/bootstrap_1.clj	Sat Apr 14 03:22:10 2012 -0500
     1.3 @@ -1,134 +1,11 @@
     1.4  (ns com.aurellem.run.bootstrap-1
     1.5    (:use (com.aurellem.gb saves gb-driver util constants
     1.6 -                         items vbm characters money))
     1.7 +                         items vbm characters money
     1.8 +                         rlm-assembly))
     1.9    (:use (com.aurellem.run util title save-corruption bootstrap-0))
    1.10    (:use (com.aurellem.exp item-bridge))
    1.11    (:import [com.aurellem.gb.gb_driver SaveState]))
    1.12  
    1.13 -(defn pc-item-writer-program
    1.14 -  []
    1.15 -  (let [limit 201
    1.16 -        [target-high target-low] (disect-bytes-2 pokemon-list-start)]
    1.17 -    (flatten
    1.18 -     [[0x00  ;; (item-hack) set increment stack pointer no-op
    1.19 -       0x1E  ;; load limit into E
    1.20 -       limit
    1.21 -       0x3F  ;; (item-hack) set carry flag no-op
    1.22 -
    1.23 -       ;; load 2 into C.
    1.24 -       0x0E   ;; C == 1 means input-first nybble
    1.25 -       0x04   ;; C == 0 means input-second nybble
    1.26 -
    1.27 -       0x21 ;; load target into HL
    1.28 -       target-low
    1.29 -       target-high
    1.30 -       0x37 ;; (item-hack) set carry flag no-op
    1.31 -
    1.32 -       0x00 ;; (item-hack) no-op
    1.33 -       0x37 ;; (item-hack) set carry flag no-op
    1.34 -       
    1.35 -       0x00 ;; (item-hack) no-op
    1.36 -       0xF3 ;; disable interrupts
    1.37 -       ;; Input Section
    1.38 -
    1.39 -       0x3E ;; load 0x20 into A, to measure buttons
    1.40 -       0x10 
    1.41 -
    1.42 -       0x00 ;; (item-hack) no-op
    1.43 -       0xE0 ;; load A into [FF00]
    1.44 -       0x00
    1.45 -
    1.46 -       0xF0 ;; load 0xFF00 into A to get
    1.47 -       0x00 ;; button presses
    1.48 -       
    1.49 -       0xE6
    1.50 -       0x0F ;; select bottom four bits of A
    1.51 -       0x37 ;; (item-hack) set carry flag no-op
    1.52 -
    1.53 -       0x00 ;; (item-hack) no-op
    1.54 -       0xB8 ;; see if input is different (CP A B)
    1.55 -
    1.56 -       0x00 ;; (item-hack) (INC SP)
    1.57 -       0x28 ;; repeat above steps if input is not different
    1.58 -       ;; (jump relative backwards if B != A)
    1.59 -       0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37)
    1.60 -
    1.61 -       0x47 ;; load A into B
    1.62 -       
    1.63 -       0x0D ;; dec C
    1.64 -       0x37 ;; (item-hack) set-carry flag
    1.65 -       ;; branch based on C:
    1.66 -       0x20 ;; JR NZ
    1.67 -       23 ;; skip "input second nybble" and "jump to target" below
    1.68 -       
    1.69 -       ;; input second nybble
    1.70 -
    1.71 -       0x0C ;; inc C
    1.72 -       0x0C ;; inc C
    1.73 -
    1.74 -       0x00 ;; (item-hack) no-op
    1.75 -       0xE6 ;; select bottom bits
    1.76 -       0x0F
    1.77 -       0x37 ;; (item-hack) set-carry flag no-op
    1.78 -
    1.79 -       0x00 ;; (item-hack) no-op
    1.80 -       0xB2 ;; (OR A D) -> A
    1.81 -
    1.82 -       0x22 ;; (do (A -> (HL)) (INC HL))
    1.83 -
    1.84 -       0x1D ;; (DEC E)
    1.85 -
    1.86 -       0x00 ;; (item-hack) 
    1.87 -       0x20 ;; jump back to input section if not done
    1.88 -       0xDA ;; literal -36 == TM 18 (counter)
    1.89 -       0x01 ;; (item-hack) set BC to literal (no-op)
    1.90 -
    1.91 -       ;; jump to target
    1.92 -       0x00  ;; (item-hack) these two bytes can be anything.
    1.93 -       0x01 
    1.94 -
    1.95 -       0x00   ;; (item-hack) no-op
    1.96 -       0xBF   ;; (CP A A) ensures Z
    1.97 -       
    1.98 -       0xCA   ;; (item-hack) jump if Z
    1.99 -       target-low
   1.100 -       target-high
   1.101 -       0x01   ;; (item-hack) will never be reached.
   1.102 -       
   1.103 -       ;; input first nybble
   1.104 -       0x00
   1.105 -       0xCB
   1.106 -       0x37  ;; swap nybbles on A
   1.107 -
   1.108 -       0x57  ;; A -> D
   1.109 -
   1.110 -       0x37  ;; (item-hack) set carry flag no-op
   1.111 -       0x18  ;; relative jump backwards
   1.112 -       0xCD  ;; literal -51 == TM05; go back to input section
   1.113 -       0x01  ;; (item-hack) will never reach this instruction
   1.114 -
   1.115 -       ]
   1.116 -      (repeat 8 [0x00 0x01]);; these can be anything
   1.117 -
   1.118 -      [;; jump to actual program
   1.119 -       0x00
   1.120 -       0x37  ;; (item-hack) set carry flag no-op
   1.121 -
   1.122 -       0x2E  ;; 0x3A -> L
   1.123 -       0x3A
   1.124 -
   1.125 -
   1.126 -       0x00  ;; (item-hack) no-op
   1.127 -       0x26  ;; 0xD5 -> L
   1.128 -       0xD5  
   1.129 -       0x01  ;; (item-hack) set-carry BC
   1.130 -
   1.131 -       0x00  ;; (item-hack) these can be anything
   1.132 -       0x01  
   1.133 -
   1.134 -       0x00
   1.135 -       0xE9 ;; jump to (HL)
   1.136 -       ]])))
   1.137  
   1.138  (defn print-desired-item-layout []
   1.139    (clojure.pprint/pprint
   1.140 @@ -882,33 +759,6 @@
   1.141  (defn control-checkpoint []
   1.142    (read-script "control-checkpoint"))
   1.143  
   1.144 -(defn no-consecutive-repeats? [seq]
   1.145 -  (not (contains? (set(map - seq (rest seq))) 0)))
   1.146 -
   1.147 -(defn byte->nybbles [byte]
   1.148 -  [(bit-shift-right byte 4) (bit-and byte 0x0F)])
   1.149 -
   1.150 -(defn bootstrap-pattern
   1.151 -  "Given an assembly sequence, generate the keypresses required to
   1.152 -   create that sequence in memory using the pc-item-writer
   1.153 -   program. The assembly must not have any consecutive repeating
   1.154 -   nybbles."
   1.155 -  [assembly]
   1.156 -  (let [nybbles (flatten (map byte->nybbles assembly))
   1.157 -        moves (map (comp buttons (partial - 15)) nybbles)
   1.158 -        header (map buttons
   1.159 -                    (concat (repeat
   1.160 -                             50
   1.161 -                             (- 15 (first nybbles)))
   1.162 -                            [(first nybbles)]))
   1.163 -        tail (map buttons
   1.164 -                  (take
   1.165 -                   (- 201 (count moves))
   1.166 -                   (interleave (repeat 100 (last nybbles))
   1.167 -                               (repeat 1000 (- 15 (last nybbles))))))]
   1.168 -    (assert (no-consecutive-repeats? nybbles))
   1.169 -    (concat header moves tail)))
   1.170 -
   1.171  (def increasing-pattern [0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF])
   1.172  
   1.173  (defn test-pattern-writing
   1.174 @@ -928,5 +778,68 @@
   1.175                         0xD162 (+ 0xD162 (count pattern)))
   1.176            pattern))))
   1.177  
   1.178 +(defn-memo launch-main-bootstrap-program
   1.179 +  ([] (launch-main-bootstrap-program
   1.180 +       (control-checkpoint)
   1.181 +       ;;(launch-bootstrap-program)
   1.182 +       ))
   1.183 +  ([script]
   1.184 +     (->> script
   1.185 +          (play-moves
   1.186 +           (bootstrap-pattern (main-bootstrap-program))))))
   1.187  
   1.188 -  
   1.189 \ No newline at end of file
   1.190 +(defn set-target-address
   1.191 +  "Assumes that the game is under control of the main-bootstrap
   1.192 +   program in MODE-SELECT mode, and sets the target address to which
   1.193 +   jumps/writes will occur."
   1.194 +  [target-address script]
   1.195 +  (let [[target-high target-low] (disect-bytes-2 target-address)]
   1.196 +    (->> script
   1.197 +         (play-moves
   1.198 +          (map buttons
   1.199 +               [set-H-mode target-high 0x00
   1.200 +                set-L-mode target-low  0x00])))))
   1.201 +                
   1.202 +(defn write-RAM
   1.203 +  "Assumes that the game is under control of the main-bootstrap
   1.204 +   program in MODE-SELECT mode, and rewrites RAM starting at
   1.205 +   'start-address with 'new-ram."
   1.206 +  [start-address new-ram script]
   1.207 +  (->> script
   1.208 +       (set-target-address start-address)
   1.209 +       (play-moves [(buttons (count new-ram))])
   1.210 +       (play-moves (map buttons new-ram))))
   1.211 +
   1.212 +(defn transfer-control
   1.213 +  "Assumes that the game is under control of the main-bootstrap
   1.214 +   program in MODE-SELECT mode, and jumps to the target-address."
   1.215 +  [target-address script]
   1.216 +  (->> script
   1.217 +       (set-target-address target-address)
   1.218 +       (play-moves [(buttons jump-mode)])))
   1.219 +
   1.220 +(defn-memo relocate-main-bootstrap
   1.221 +  ([] (relocate-main-bootstrap (launch-main-bootstrap-program)))
   1.222 +  ([script]
   1.223 +     (let [target (+ 90 pokemon-box-1-address)]
   1.224 +       (->> script
   1.225 +            (write-RAM target (main-bootstrap-program target))
   1.226 +            (transfer-control target)))))
   1.227 +
   1.228 +(def mid-game-data
   1.229 +  (subvec (vec (memory (mid-game)))
   1.230 +          pokemon-list-start
   1.231 +          (+ pokemon-list-start 700)))
   1.232 +
   1.233 +(def mid-game-map-address 0x46BC)
   1.234 +
   1.235 +(defn set-mid-game-data
   1.236 +  ([] (set-mid-game-data (relocate-main-bootstrap)))
   1.237 +  ([script]
   1.238 +     (->> script
   1.239 +          (write-RAM pokemon-list-start mid-game-data)
   1.240 +          (transfer-control mid-game-map-address))))
   1.241 +
   1.242 +
   1.243 +
   1.244 +