Mercurial > vba-clojure
comparison clojure/com/aurellem/gb/rlm_assembly.clj @ 390:dbf7b5a2e9e7
saving progress.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Wed, 11 Apr 2012 23:40:01 -0500 |
parents | bb8978d370d8 |
children | 2e9b2d27f32f |
comparison
equal
deleted
inserted
replaced
389:bb8978d370d8 | 390:dbf7b5a2e9e7 |
---|---|
2 "Version of main bootstrap program that is valid output for the | 2 "Version of main bootstrap program that is valid output for the |
3 item-writer program." | 3 item-writer program." |
4 (:use (com.aurellem.gb gb-driver assembly util vbm constants)) | 4 (:use (com.aurellem.gb gb-driver assembly util vbm constants)) |
5 (:use (com.aurellem.run bootstrap-1)) | 5 (:use (com.aurellem.run bootstrap-1)) |
6 (:import [com.aurellem.gb.gb_driver SaveState])) | 6 (:import [com.aurellem.gb.gb_driver SaveState])) |
7 | |
8 | |
9 ;; MODE-SELECT | |
10 ;; SET-LENGTH | |
11 ;; SET-TARGET | |
12 ;; WRITE | |
13 ;; JUMP | |
7 | 14 |
8 ;; Specs for Main Bootstrap Program | 15 ;; Specs for Main Bootstrap Program |
9 | 16 |
10 ;; Number-Input | 17 ;; Number-Input |
11 ;; Number input works using all eight buttons to | 18 ;; Number input works using all eight buttons to |
62 (defn ->signed-8-bit [n] | 69 (defn ->signed-8-bit [n] |
63 (if (< n 0) | 70 (if (< n 0) |
64 (+ 256 n) n)) | 71 (+ 256 n) n)) |
65 | 72 |
66 (defn frame-metronome [] | 73 (defn frame-metronome [] |
67 (let [timing-loop | 74 (let [init [0xC5] ;; save value of BC |
75 timing-loop | |
68 [0x01 ; \ | 76 [0x01 ; \ |
69 0x43 ; | | 77 0x43 ; | |
70 0xFE ; | load 0xFF44 into BC without repeats | 78 0xFE ; | load 0xFF44 into BC without repeats |
71 0x0C ; | | 79 0x0C ; | |
72 0x04 ; / | 80 0x04 ; / |
79 (+ -4 (- (count timing-loop))))] | 87 (+ -4 (- (count timing-loop))))] |
80 spin-loop | 88 spin-loop |
81 [0x05 ;; dec B, which is 0xFF | 89 [0x05 ;; dec B, which is 0xFF |
82 0x20 ;; spin until B==0 | 90 0x20 ;; spin until B==0 |
83 0xFD]] | 91 0xFD]] |
84 (concat timing-loop continue-if-144 spin-loop))) | 92 (concat init timing-loop continue-if-144 spin-loop))) |
85 | 93 |
86 (defn test-frame-metronome | 94 (defn test-frame-metronome |
87 "Ensure that frame-metronome ticks exactly once every frame." | 95 "Ensure that frame-metronome ticks exactly once every frame." |
88 ([] (test-frame-metronome 151)) | 96 ([] (test-frame-metronome 151)) |
89 ([steps] | 97 ([steps] |
95 (-> (tick (mid-game)) | 103 (-> (tick (mid-game)) |
96 (IE! 0) | 104 (IE! 0) |
97 (DE! 0) | 105 (DE! 0) |
98 (set-memory-range pokemon-list-start program) | 106 (set-memory-range pokemon-list-start program) |
99 (PC! pokemon-list-start)) | 107 (PC! pokemon-list-start)) |
100 E-after-moves (E (run-moves count-frames (repeat steps [])))] | 108 E-after-moves |
109 (E (run-moves count-frames (repeat steps [])))] | |
101 (println "E:" E-after-moves) | 110 (println "E:" E-after-moves) |
102 (assert (= steps E-after-moves)) | 111 (assert (= steps E-after-moves)) |
103 | 112 |
104 (println "E =" E-after-moves "after" steps "steps") | 113 (println "E =" E-after-moves "after" steps "steps") |
105 count-frames))) | 114 count-frames))) |
141 0x37 ;; swap A nybbles | 150 0x37 ;; swap A nybbles |
142 | 151 |
143 0xB0 ;; (or A B) -> A | 152 0xB0 ;; (or A B) -> A |
144 | 153 |
145 0x2F ;; (NOT A) -> A | 154 0x2F ;; (NOT A) -> A |
155 | |
146 ]) | 156 ]) |
147 | 157 |
148 (defn test-read-user-input [] | 158 (defn test-read-user-input [] |
149 (let [program | 159 (let [program |
150 (concat | 160 (concat |
177 | 187 |
178 (def input-write-num-mode (Integer/parseInt "00001000" 2)) | 188 (def input-write-num-mode (Integer/parseInt "00001000" 2)) |
179 (def do-write-mode (Integer/parseInt "00010000" 2)) | 189 (def do-write-mode (Integer/parseInt "00010000" 2)) |
180 | 190 |
181 (defn main-bootstrap-program [start-address] | 191 (defn main-bootstrap-program [start-address] |
192 ;; Register Use: | |
193 | |
194 ;; BC persistent scratch | |
195 ;; | |
196 ;; A user-input | |
197 ;; HL target-address | |
198 ;; D current-mode | |
199 ;; E bytes-to-write | |
200 | |
201 | |
202 ;; Modes are: | |
203 | |
204 ;; single-action-modes: | |
205 ;; SET-MODE | |
206 ;; SET-TARGET-HIGH | |
207 ;; SET-TARGET-LOW | |
208 ;; SET-WRITE-LENGTH | |
209 ;; JUMP | |
210 | |
211 ;; multi-action-modes | |
212 ;; WRITE | |
213 | |
214 | |
215 | |
182 (let [[start-high start-low] (disect-bytes-2 start-address) | 216 (let [[start-high start-low] (disect-bytes-2 start-address) |
183 jump-distance (+ (count (frame-metronome) | 217 jump-distance (+ (count (frame-metronome)) |
184 (read-user-input))) | 218 (read-user-input)) |
185 | 219 |
186 init | 220 init |
187 [0xAF 0x5F] ;; 0->A; 0->E; | 221 [0xAF 0x5F 0x57 0x47] ;; 0->A; 0->E; 0->D; 0->B |
188 | 222 |
189 | 223 |
190 header | 224 |
191 [0x47] ;; A->B | 225 |
192 | 226 input |
193 mode-select | 227 [0xC1 ;; pop BC so it's not volatile |
194 [0xCB 0x43 ;; last-bit is zero | 228 ;; some condition |
195 0x28 :to-beginning | 229 ;; to skip if not in input |
196 0x5F];; A->E | 230 ;; mode |
197 | 231 |
198 input-section | 232 |
199 [0xCB 0x4B ;; test bit 0 of E | 233 |
200 0x28 0x03 | 234 |
201 | 235 0xE9 ;; jump to (HL) |
202 | 236 |
237 0x22 ;; A->(HL) ; inc HL | |
238 | |
239 | |
203 0x57 ;; A->D | 240 0x57 ;; A->D |
204 | 241 |
205 0x67 ;; A->H | 242 0x67 ;; A->H |
206 0x6F ;; A->L | 243 0x6F ;; A->L |
207 | 244 |
217 | 254 |
218 ;; HL = here | 255 ;; HL = here |
219 ;; add C to HL | 256 ;; add C to HL |
220 ;; jp HL | 257 ;; jp HL |
221 | 258 |
222 prepare-HL | 259 ]])) |
223 [0xD1 ;; pop DE causes D and E to be non-volitale | |
224 | |
225 0x21 ;; load HL from literal nn | |
226 :dispatch-high | |
227 :dispatch-low] | |
228 | |
229 mode-dispatch | |
230 [0xC5 ;; push BC | |
231 0x06 ;\ | |
232 0x01 ; | 0->B without repeats | |
233 0x05 ;/ | |
234 0x09 ;; add BC to HL | |
235 0xC1 ;; pop BC | |
236 0xE9] ;; jp | |
237 | |
238 mode-select | |
239 [0x4F ;; A->C (this is the address of dispatch above) | |
240 0x18 ;; return | |
241 :jump-to-end] | |
242 | |
243 input-bytes-to-write | |
244 [0x47 ;; A->B | |
245 0x18 ;; return | |
246 :jump-to-end] | |
247 | |
248 | |
249 | |
250 | |
251 | |
252 cleanup | |
253 [0xD5 ;; push DE | |
254 0x18 | |
255 0x??];; jump all the way back to frame-metronome | |
256 | |
257 | |
258 ;; (concat init (frame-metronome) (read-user-input) | |
259 ;; prepare-HL here mode-dispatch) | |
260 | |
261 | |
262 | |
263 | |
264 | |
265 | |
266 | |
267 | |
268 ;; )) | |
269 | |
270 | 260 |
271 | 261 |
272 | 262 |
273 | 263 |
274 | 264 |