Mercurial > vba-clojure
comparison 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 |
comparison
equal
deleted
inserted
replaced
413:70e313aeaa91 | 414:0162dd315814 |
---|---|
1 (ns com.aurellem.gb.rlm-assembly | 1 (ns com.aurellem.gb.rlm-assembly |
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)) | |
6 (:import [com.aurellem.gb.gb_driver SaveState])) | 5 (:import [com.aurellem.gb.gb_driver SaveState])) |
6 | |
7 (defn pc-item-writer-program | |
8 [] | |
9 (let [limit 201 | |
10 [target-high target-low] (disect-bytes-2 pokemon-list-start)] | |
11 (flatten | |
12 [[0x00 ;; (item-hack) set increment stack pointer no-op | |
13 0x1E ;; load limit into E | |
14 limit | |
15 0x3F ;; (item-hack) set carry flag no-op | |
16 | |
17 ;; load 2 into C. | |
18 0x0E ;; C == 1 means input-first nybble | |
19 0x04 ;; C == 0 means input-second nybble | |
20 | |
21 0x21 ;; load target into HL | |
22 target-low | |
23 target-high | |
24 0x37 ;; (item-hack) set carry flag no-op | |
25 | |
26 0x00 ;; (item-hack) no-op | |
27 0x37 ;; (item-hack) set carry flag no-op | |
28 | |
29 0x00 ;; (item-hack) no-op | |
30 0xF3 ;; disable interrupts | |
31 ;; Input Section | |
32 | |
33 0x3E ;; load 0x20 into A, to measure buttons | |
34 0x10 | |
35 | |
36 0x00 ;; (item-hack) no-op | |
37 0xE0 ;; load A into [FF00] | |
38 0x00 | |
39 | |
40 0xF0 ;; load 0xFF00 into A to get | |
41 0x00 ;; button presses | |
42 | |
43 0xE6 | |
44 0x0F ;; select bottom four bits of A | |
45 0x37 ;; (item-hack) set carry flag no-op | |
46 | |
47 0x00 ;; (item-hack) no-op | |
48 0xB8 ;; see if input is different (CP A B) | |
49 | |
50 0x00 ;; (item-hack) (INC SP) | |
51 0x28 ;; repeat above steps if input is not different | |
52 ;; (jump relative backwards if B != A) | |
53 0xED ;; (literal -19) (item-hack) -19 == egg bomb (TM37) | |
54 | |
55 0x47 ;; load A into B | |
56 | |
57 0x0D ;; dec C | |
58 0x37 ;; (item-hack) set-carry flag | |
59 ;; branch based on C: | |
60 0x20 ;; JR NZ | |
61 23 ;; skip "input second nybble" and "jump to target" below | |
62 | |
63 ;; input second nybble | |
64 | |
65 0x0C ;; inc C | |
66 0x0C ;; inc C | |
67 | |
68 0x00 ;; (item-hack) no-op | |
69 0xE6 ;; select bottom bits | |
70 0x0F | |
71 0x37 ;; (item-hack) set-carry flag no-op | |
72 | |
73 0x00 ;; (item-hack) no-op | |
74 0xB2 ;; (OR A D) -> A | |
75 | |
76 0x22 ;; (do (A -> (HL)) (INC HL)) | |
77 | |
78 0x1D ;; (DEC E) | |
79 | |
80 0x00 ;; (item-hack) | |
81 0x20 ;; jump back to input section if not done | |
82 0xDA ;; literal -36 == TM 18 (counter) | |
83 0x01 ;; (item-hack) set BC to literal (no-op) | |
84 | |
85 ;; jump to target | |
86 0x00 ;; (item-hack) these two bytes can be anything. | |
87 0x01 | |
88 | |
89 0x00 ;; (item-hack) no-op | |
90 0xBF ;; (CP A A) ensures Z | |
91 | |
92 0xCA ;; (item-hack) jump if Z | |
93 target-low | |
94 target-high | |
95 0x01 ;; (item-hack) will never be reached. | |
96 | |
97 ;; input first nybble | |
98 0x00 | |
99 0xCB | |
100 0x37 ;; swap nybbles on A | |
101 | |
102 0x57 ;; A -> D | |
103 | |
104 0x37 ;; (item-hack) set carry flag no-op | |
105 0x18 ;; relative jump backwards | |
106 0xCD ;; literal -51 == TM05; go back to input section | |
107 0x01 ;; (item-hack) will never reach this instruction | |
108 | |
109 ] | |
110 (repeat 8 [0x00 0x01]);; these can be anything | |
111 | |
112 [;; jump to actual program | |
113 0x00 | |
114 0x37 ;; (item-hack) set carry flag no-op | |
115 | |
116 0x2E ;; 0x3A -> L | |
117 0x3A | |
118 | |
119 | |
120 0x00 ;; (item-hack) no-op | |
121 0x26 ;; 0xD5 -> L | |
122 0xD5 | |
123 0x01 ;; (item-hack) set-carry BC | |
124 | |
125 0x00 ;; (item-hack) these can be anything | |
126 0x01 | |
127 | |
128 0x00 | |
129 0xE9 ;; jump to (HL) | |
130 ]]))) | |
7 | 131 |
8 | 132 |
9 | 133 |
10 ;; Specs for Main Bootstrap Program | 134 ;; Specs for Main Bootstrap Program |
11 | 135 |
337 (- (symbol-index :to-beginning program*))))} | 461 (- (symbol-index :to-beginning program*))))} |
338 | 462 |
339 program | 463 program |
340 (replace resolve-external-jumps program*)] | 464 (replace resolve-external-jumps program*)] |
341 program))) | 465 program))) |
342 | 466 |
467 | |
468 (defn no-consecutive-repeats? [seq] | |
469 (not (contains? (set(map - seq (rest seq))) 0))) | |
470 | |
471 (defn byte->nybbles [byte] | |
472 [(bit-shift-right byte 4) (bit-and byte 0x0F)]) | |
473 | |
474 (defn bootstrap-pattern | |
475 "Given an assembly sequence, generate the keypresses required to | |
476 create that sequence in memory using the pc-item-writer | |
477 program. The assembly must not have any consecutive repeating | |
478 nybbles." | |
479 [assembly] | |
480 (let [nybbles (flatten (map byte->nybbles assembly)) | |
481 moves (map (comp buttons (partial - 15)) nybbles) | |
482 header (map buttons | |
483 (concat (repeat | |
484 50 | |
485 (- 15 (first nybbles))) | |
486 [(first nybbles)])) | |
487 tail (map buttons | |
488 (take | |
489 (- 201 (count moves)) | |
490 (interleave (repeat 100 (last nybbles)) | |
491 (repeat 1000 (- 15 (last nybbles))))))] | |
492 (assert (no-consecutive-repeats? nybbles)) | |
493 (concat header moves tail))) | |
343 | 494 |
344 ;;;;;; TESTS ;;;;;; | 495 ;;;;;; TESTS ;;;;;; |
345 | 496 |
346 (def set-H-mode 0x67) | 497 (def set-H-mode 0x67) |
347 (def set-L-mode 0x6F) | 498 (def set-L-mode 0x6F) |