comparison 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
comparison
equal deleted inserted replaced
413:70e313aeaa91 414:0162dd315814
1 (ns com.aurellem.run.bootstrap-1 1 (ns com.aurellem.run.bootstrap-1
2 (:use (com.aurellem.gb saves gb-driver util constants 2 (:use (com.aurellem.gb saves gb-driver util constants
3 items vbm characters money)) 3 items vbm characters money
4 rlm-assembly))
4 (:use (com.aurellem.run util title save-corruption bootstrap-0)) 5 (:use (com.aurellem.run util title save-corruption bootstrap-0))
5 (:use (com.aurellem.exp item-bridge)) 6 (:use (com.aurellem.exp item-bridge))
6 (:import [com.aurellem.gb.gb_driver SaveState])) 7 (:import [com.aurellem.gb.gb_driver SaveState]))
7 8
8 (defn pc-item-writer-program
9 []
10 (let [limit 201
11 [target-high target-low] (disect-bytes-2 pokemon-list-start)]
12 (flatten
13 [[0x00 ;; (item-hack) set increment stack pointer no-op
14 0x1E ;; load limit into E
15 limit
16 0x3F ;; (item-hack) set carry flag no-op
17
18 ;; load 2 into C.
19 0x0E ;; C == 1 means input-first nybble
20 0x04 ;; C == 0 means input-second nybble
21
22 0x21 ;; load target into HL
23 target-low
24 target-high
25 0x37 ;; (item-hack) set carry flag no-op
26
27 0x00 ;; (item-hack) no-op
28 0x37 ;; (item-hack) set carry flag no-op
29
30 0x00 ;; (item-hack) no-op
31 0xF3 ;; disable interrupts
32 ;; Input Section
33
34 0x3E ;; load 0x20 into A, to measure buttons
35 0x10
36
37 0x00 ;; (item-hack) no-op
38 0xE0 ;; load A into [FF00]
39 0x00
40
41 0xF0 ;; load 0xFF00 into A to get
42 0x00 ;; button presses
43
44 0xE6
45 0x0F ;; select bottom four bits of A
46 0x37 ;; (item-hack) set carry flag no-op
47
48 0x00 ;; (item-hack) no-op
49 0xB8 ;; see if input is different (CP A B)
50
51 0x00 ;; (item-hack) (INC SP)
52 0x28 ;; repeat above steps if input is not different
53 ;; (jump relative backwards if B != A)
54 0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37)
55
56 0x47 ;; load A into B
57
58 0x0D ;; dec C
59 0x37 ;; (item-hack) set-carry flag
60 ;; branch based on C:
61 0x20 ;; JR NZ
62 23 ;; skip "input second nybble" and "jump to target" below
63
64 ;; input second nybble
65
66 0x0C ;; inc C
67 0x0C ;; inc C
68
69 0x00 ;; (item-hack) no-op
70 0xE6 ;; select bottom bits
71 0x0F
72 0x37 ;; (item-hack) set-carry flag no-op
73
74 0x00 ;; (item-hack) no-op
75 0xB2 ;; (OR A D) -> A
76
77 0x22 ;; (do (A -> (HL)) (INC HL))
78
79 0x1D ;; (DEC E)
80
81 0x00 ;; (item-hack)
82 0x20 ;; jump back to input section if not done
83 0xDA ;; literal -36 == TM 18 (counter)
84 0x01 ;; (item-hack) set BC to literal (no-op)
85
86 ;; jump to target
87 0x00 ;; (item-hack) these two bytes can be anything.
88 0x01
89
90 0x00 ;; (item-hack) no-op
91 0xBF ;; (CP A A) ensures Z
92
93 0xCA ;; (item-hack) jump if Z
94 target-low
95 target-high
96 0x01 ;; (item-hack) will never be reached.
97
98 ;; input first nybble
99 0x00
100 0xCB
101 0x37 ;; swap nybbles on A
102
103 0x57 ;; A -> D
104
105 0x37 ;; (item-hack) set carry flag no-op
106 0x18 ;; relative jump backwards
107 0xCD ;; literal -51 == TM05; go back to input section
108 0x01 ;; (item-hack) will never reach this instruction
109
110 ]
111 (repeat 8 [0x00 0x01]);; these can be anything
112
113 [;; jump to actual program
114 0x00
115 0x37 ;; (item-hack) set carry flag no-op
116
117 0x2E ;; 0x3A -> L
118 0x3A
119
120
121 0x00 ;; (item-hack) no-op
122 0x26 ;; 0xD5 -> L
123 0xD5
124 0x01 ;; (item-hack) set-carry BC
125
126 0x00 ;; (item-hack) these can be anything
127 0x01
128
129 0x00
130 0xE9 ;; jump to (HL)
131 ]])))
132 9
133 (defn print-desired-item-layout [] 10 (defn print-desired-item-layout []
134 (clojure.pprint/pprint 11 (clojure.pprint/pprint
135 (raw-inventory->inventory (pc-item-writer-program)))) 12 (raw-inventory->inventory (pc-item-writer-program))))
136 13
880 [] (write-script! (launch-bootstrap-program) "control-checkpoint")) 757 [] (write-script! (launch-bootstrap-program) "control-checkpoint"))
881 758
882 (defn control-checkpoint [] 759 (defn control-checkpoint []
883 (read-script "control-checkpoint")) 760 (read-script "control-checkpoint"))
884 761
885 (defn no-consecutive-repeats? [seq]
886 (not (contains? (set(map - seq (rest seq))) 0)))
887
888 (defn byte->nybbles [byte]
889 [(bit-shift-right byte 4) (bit-and byte 0x0F)])
890
891 (defn bootstrap-pattern
892 "Given an assembly sequence, generate the keypresses required to
893 create that sequence in memory using the pc-item-writer
894 program. The assembly must not have any consecutive repeating
895 nybbles."
896 [assembly]
897 (let [nybbles (flatten (map byte->nybbles assembly))
898 moves (map (comp buttons (partial - 15)) nybbles)
899 header (map buttons
900 (concat (repeat
901 50
902 (- 15 (first nybbles)))
903 [(first nybbles)]))
904 tail (map buttons
905 (take
906 (- 201 (count moves))
907 (interleave (repeat 100 (last nybbles))
908 (repeat 1000 (- 15 (last nybbles))))))]
909 (assert (no-consecutive-repeats? nybbles))
910 (concat header moves tail)))
911
912 (def increasing-pattern [0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF]) 762 (def increasing-pattern [0x01 0x23 0x45 0x67 0x89 0xAB 0xCD 0xEF])
913 763
914 (defn test-pattern-writing 764 (defn test-pattern-writing
915 ([] (test-pattern-writing increasing-pattern)) 765 ([] (test-pattern-writing increasing-pattern))
916 ([pattern] 766 ([pattern]
926 0xD162 (+ 0xD162 (count pattern))) 776 0xD162 (+ 0xD162 (count pattern)))
927 (= (subvec (vec (memory (second pattern-insertion))) 777 (= (subvec (vec (memory (second pattern-insertion)))
928 0xD162 (+ 0xD162 (count pattern))) 778 0xD162 (+ 0xD162 (count pattern)))
929 pattern)))) 779 pattern))))
930 780
931 781 (defn-memo launch-main-bootstrap-program
932 782 ([] (launch-main-bootstrap-program
783 (control-checkpoint)
784 ;;(launch-bootstrap-program)
785 ))
786 ([script]
787 (->> script
788 (play-moves
789 (bootstrap-pattern (main-bootstrap-program))))))
790
791 (defn set-target-address
792 "Assumes that the game is under control of the main-bootstrap
793 program in MODE-SELECT mode, and sets the target address to which
794 jumps/writes will occur."
795 [target-address script]
796 (let [[target-high target-low] (disect-bytes-2 target-address)]
797 (->> script
798 (play-moves
799 (map buttons
800 [set-H-mode target-high 0x00
801 set-L-mode target-low 0x00])))))
802
803 (defn write-RAM
804 "Assumes that the game is under control of the main-bootstrap
805 program in MODE-SELECT mode, and rewrites RAM starting at
806 'start-address with 'new-ram."
807 [start-address new-ram script]
808 (->> script
809 (set-target-address start-address)
810 (play-moves [(buttons (count new-ram))])
811 (play-moves (map buttons new-ram))))
812
813 (defn transfer-control
814 "Assumes that the game is under control of the main-bootstrap
815 program in MODE-SELECT mode, and jumps to the target-address."
816 [target-address script]
817 (->> script
818 (set-target-address target-address)
819 (play-moves [(buttons jump-mode)])))
820
821 (defn-memo relocate-main-bootstrap
822 ([] (relocate-main-bootstrap (launch-main-bootstrap-program)))
823 ([script]
824 (let [target (+ 90 pokemon-box-1-address)]
825 (->> script
826 (write-RAM target (main-bootstrap-program target))
827 (transfer-control target)))))
828
829 (def mid-game-data
830 (subvec (vec (memory (mid-game)))
831 pokemon-list-start
832 (+ pokemon-list-start 700)))
833
834 (def mid-game-map-address 0x46BC)
835
836 (defn set-mid-game-data
837 ([] (set-mid-game-data (relocate-main-bootstrap)))
838 ([script]
839 (->> script
840 (write-RAM pokemon-list-start mid-game-data)
841 (transfer-control mid-game-map-address))))
842
843
844
845