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)