diff clojure/com/aurellem/gb/rlm_assembly.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 55a45f67e4a4
children f2f1e0b8c1c7
line wrap: on
line diff
     1.1 --- a/clojure/com/aurellem/gb/rlm_assembly.clj	Sat Apr 14 01:32:49 2012 -0500
     1.2 +++ b/clojure/com/aurellem/gb/rlm_assembly.clj	Sat Apr 14 03:22:10 2012 -0500
     1.3 @@ -2,9 +2,133 @@
     1.4    "Version of main bootstrap program that is valid output for the
     1.5     item-writer program."
     1.6    (:use (com.aurellem.gb gb-driver assembly util vbm constants))
     1.7 -  (:use (com.aurellem.run bootstrap-1))
     1.8    (:import [com.aurellem.gb.gb_driver SaveState]))
     1.9  
    1.10 +(defn pc-item-writer-program
    1.11 +  []
    1.12 +  (let [limit 201
    1.13 +        [target-high target-low] (disect-bytes-2 pokemon-list-start)]
    1.14 +    (flatten
    1.15 +     [[0x00  ;; (item-hack) set increment stack pointer no-op
    1.16 +       0x1E  ;; load limit into E
    1.17 +       limit
    1.18 +       0x3F  ;; (item-hack) set carry flag no-op
    1.19 +
    1.20 +       ;; load 2 into C.
    1.21 +       0x0E   ;; C == 1 means input-first nybble
    1.22 +       0x04   ;; C == 0 means input-second nybble
    1.23 +
    1.24 +       0x21 ;; load target into HL
    1.25 +       target-low
    1.26 +       target-high
    1.27 +       0x37 ;; (item-hack) set carry flag no-op
    1.28 +
    1.29 +       0x00 ;; (item-hack) no-op
    1.30 +       0x37 ;; (item-hack) set carry flag no-op
    1.31 +       
    1.32 +       0x00 ;; (item-hack) no-op
    1.33 +       0xF3 ;; disable interrupts
    1.34 +       ;; Input Section
    1.35 +
    1.36 +       0x3E ;; load 0x20 into A, to measure buttons
    1.37 +       0x10 
    1.38 +
    1.39 +       0x00 ;; (item-hack) no-op
    1.40 +       0xE0 ;; load A into [FF00]
    1.41 +       0x00
    1.42 +
    1.43 +       0xF0 ;; load 0xFF00 into A to get
    1.44 +       0x00 ;; button presses
    1.45 +       
    1.46 +       0xE6
    1.47 +       0x0F ;; select bottom four bits of A
    1.48 +       0x37 ;; (item-hack) set carry flag no-op
    1.49 +
    1.50 +       0x00 ;; (item-hack) no-op
    1.51 +       0xB8 ;; see if input is different (CP A B)
    1.52 +
    1.53 +       0x00 ;; (item-hack) (INC SP)
    1.54 +       0x28 ;; repeat above steps if input is not different
    1.55 +       ;; (jump relative backwards if B != A)
    1.56 +       0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37)
    1.57 +
    1.58 +       0x47 ;; load A into B
    1.59 +       
    1.60 +       0x0D ;; dec C
    1.61 +       0x37 ;; (item-hack) set-carry flag
    1.62 +       ;; branch based on C:
    1.63 +       0x20 ;; JR NZ
    1.64 +       23 ;; skip "input second nybble" and "jump to target" below
    1.65 +       
    1.66 +       ;; input second nybble
    1.67 +
    1.68 +       0x0C ;; inc C
    1.69 +       0x0C ;; inc C
    1.70 +
    1.71 +       0x00 ;; (item-hack) no-op
    1.72 +       0xE6 ;; select bottom bits
    1.73 +       0x0F
    1.74 +       0x37 ;; (item-hack) set-carry flag no-op
    1.75 +
    1.76 +       0x00 ;; (item-hack) no-op
    1.77 +       0xB2 ;; (OR A D) -> A
    1.78 +
    1.79 +       0x22 ;; (do (A -> (HL)) (INC HL))
    1.80 +
    1.81 +       0x1D ;; (DEC E)
    1.82 +
    1.83 +       0x00 ;; (item-hack) 
    1.84 +       0x20 ;; jump back to input section if not done
    1.85 +       0xDA ;; literal -36 == TM 18 (counter)
    1.86 +       0x01 ;; (item-hack) set BC to literal (no-op)
    1.87 +
    1.88 +       ;; jump to target
    1.89 +       0x00  ;; (item-hack) these two bytes can be anything.
    1.90 +       0x01 
    1.91 +
    1.92 +       0x00   ;; (item-hack) no-op
    1.93 +       0xBF   ;; (CP A A) ensures Z
    1.94 +       
    1.95 +       0xCA   ;; (item-hack) jump if Z
    1.96 +       target-low
    1.97 +       target-high
    1.98 +       0x01   ;; (item-hack) will never be reached.
    1.99 +       
   1.100 +       ;; input first nybble
   1.101 +       0x00
   1.102 +       0xCB
   1.103 +       0x37  ;; swap nybbles on A
   1.104 +
   1.105 +       0x57  ;; A -> D
   1.106 +
   1.107 +       0x37  ;; (item-hack) set carry flag no-op
   1.108 +       0x18  ;; relative jump backwards
   1.109 +       0xCD  ;; literal -51 == TM05; go back to input section
   1.110 +       0x01  ;; (item-hack) will never reach this instruction
   1.111 +
   1.112 +       ]
   1.113 +      (repeat 8 [0x00 0x01]);; these can be anything
   1.114 +
   1.115 +      [;; jump to actual program
   1.116 +       0x00
   1.117 +       0x37  ;; (item-hack) set carry flag no-op
   1.118 +
   1.119 +       0x2E  ;; 0x3A -> L
   1.120 +       0x3A
   1.121 +
   1.122 +
   1.123 +       0x00  ;; (item-hack) no-op
   1.124 +       0x26  ;; 0xD5 -> L
   1.125 +       0xD5  
   1.126 +       0x01  ;; (item-hack) set-carry BC
   1.127 +
   1.128 +       0x00  ;; (item-hack) these can be anything
   1.129 +       0x01  
   1.130 +
   1.131 +       0x00
   1.132 +       0xE9 ;; jump to (HL)
   1.133 +       ]])))
   1.134 +
   1.135  
   1.136  
   1.137  ;; Specs for Main Bootstrap Program
   1.138 @@ -339,7 +463,34 @@
   1.139             program
   1.140             (replace resolve-external-jumps program*)]
   1.141         program)))
   1.142 -        
   1.143 +
   1.144 +
   1.145 +(defn no-consecutive-repeats? [seq]
   1.146 +  (not (contains? (set(map - seq (rest seq))) 0)))
   1.147 +
   1.148 +(defn byte->nybbles [byte]
   1.149 +  [(bit-shift-right byte 4) (bit-and byte 0x0F)])
   1.150 +
   1.151 +(defn bootstrap-pattern
   1.152 +  "Given an assembly sequence, generate the keypresses required to
   1.153 +   create that sequence in memory using the pc-item-writer
   1.154 +   program. The assembly must not have any consecutive repeating
   1.155 +   nybbles."
   1.156 +  [assembly]
   1.157 +  (let [nybbles (flatten (map byte->nybbles assembly))
   1.158 +        moves (map (comp buttons (partial - 15)) nybbles)
   1.159 +        header (map buttons
   1.160 +                    (concat (repeat
   1.161 +                             50
   1.162 +                             (- 15 (first nybbles)))
   1.163 +                            [(first nybbles)]))
   1.164 +        tail (map buttons
   1.165 +                  (take
   1.166 +                   (- 201 (count moves))
   1.167 +                   (interleave (repeat 100 (last nybbles))
   1.168 +                               (repeat 1000 (- 15 (last nybbles))))))]
   1.169 +    (assert (no-consecutive-repeats? nybbles))
   1.170 +    (concat header moves tail)))
   1.171      
   1.172  ;;;;;; TESTS ;;;;;;
   1.173