rlm@239
|
1 (ns com.aurellem.gb.dylan-assembly
|
rlm@239
|
2 "A much more compact version of write-memory-assembly"
|
rlm@239
|
3 {:author "Dylan Holmes"}
|
rlm@239
|
4 (:use (com.aurellem.gb gb-driver assembly util))
|
rlm@239
|
5 (:import [com.aurellem.gb.gb_driver SaveState]))
|
rlm@239
|
6
|
rlm@239
|
7 (defn write-memory-assembly-compact
|
rlm@239
|
8 "Currently, grabs input from the user each frame."
|
rlm@239
|
9 []
|
rlm@239
|
10 [
|
rlm@239
|
11 ;; --------- FRAME METRONOME
|
rlm@239
|
12 0x18 ;; jump ahead to cleanup. first time only.
|
rlm@239
|
13 0x40 ;; v-blank-prev [D31E]
|
rlm@239
|
14
|
rlm@239
|
15 0xFA ;; load modes into A [D31F]
|
rlm@239
|
16 0x41
|
rlm@239
|
17 0xFF
|
rlm@239
|
18
|
rlm@239
|
19 0x47 ;; A -> B
|
rlm@239
|
20 0xCB ;; rotate A
|
rlm@239
|
21 0x2F
|
rlm@239
|
22 0x2F ;; invert A
|
rlm@239
|
23
|
rlm@239
|
24 0xA0
|
rlm@239
|
25 0x47 ;; now B_0 contains (VB==1)
|
rlm@239
|
26
|
rlm@239
|
27 0xFA ;; load v-blank-prev
|
rlm@239
|
28 0x1E
|
rlm@239
|
29 0xD3
|
rlm@239
|
30
|
rlm@239
|
31 0x2F ;; complement v-blank-prev
|
rlm@239
|
32
|
rlm@239
|
33 0xA0 ;; A & B --> A
|
rlm@239
|
34 0x4F ;; now C_0 contains increment?
|
rlm@239
|
35
|
rlm@239
|
36
|
rlm@239
|
37 0x78 ;; B->A
|
rlm@239
|
38 0xEA ;; spit A --> vbprev
|
rlm@239
|
39 0x1E
|
rlm@239
|
40 0xD3
|
rlm@239
|
41
|
rlm@239
|
42 0xCB ;test C_0
|
rlm@239
|
43 0x41
|
rlm@239
|
44 0x20 ; JUMP ahead to button input if nonzero
|
rlm@239
|
45 0x02
|
rlm@239
|
46 0x18 ; JUMP back to frame metronome (D31F)
|
rlm@239
|
47 0xE7
|
rlm@239
|
48
|
rlm@239
|
49 ;; -------- GET BUTTON INPUT
|
rlm@239
|
50
|
rlm@239
|
51 ;; btw, C_0 is now 1
|
rlm@239
|
52 ;; prepare to select bits
|
rlm@239
|
53
|
rlm@239
|
54 0x06 ;; load 0x00 into B
|
rlm@239
|
55 0x00 ;; to initialize for "OR" loop
|
rlm@239
|
56
|
rlm@239
|
57 0x3E ;; load 0x20 into A, to measure dpad
|
rlm@239
|
58 0x20
|
rlm@239
|
59
|
rlm@239
|
60
|
rlm@239
|
61 0xE0 ;; load A into [FF00] ;; start of OR loop [D33C]
|
rlm@239
|
62 0x00
|
rlm@239
|
63
|
rlm@239
|
64 0xF0 ;; load A from [FF00]
|
rlm@239
|
65 0x00
|
rlm@239
|
66
|
rlm@239
|
67 0xE6 ;; bitmask 00001111
|
rlm@239
|
68 0x0F
|
rlm@239
|
69
|
rlm@239
|
70 0xB0 ;; A or B --> A
|
rlm@239
|
71 0xCB
|
rlm@239
|
72 0x41 ;; test bit 0 of C
|
rlm@239
|
73 0x28 ;; JUMP forward if 0
|
rlm@239
|
74 0x08
|
rlm@239
|
75
|
rlm@239
|
76 0x47 ;; A -> B
|
rlm@239
|
77 0xCB ;; swap B nybbles
|
rlm@239
|
78 0x30
|
rlm@239
|
79 0x0C ;; increment C
|
rlm@239
|
80 0x3E ;; load 0x10 into A, to measure btns
|
rlm@239
|
81 0x10
|
rlm@239
|
82 0x18 ;; JUMP back to "load A into [FF00]" [20 steps?]
|
rlm@239
|
83 0xED
|
rlm@239
|
84
|
rlm@239
|
85
|
rlm@239
|
86 ;; ------ TAKE ACTION BASED ON USER INPUT
|
rlm@239
|
87
|
rlm@239
|
88 ;; "input mode"
|
rlm@239
|
89 ;; mode 0x00 : select mode
|
rlm@239
|
90 ;; mode 0x08 : select bytes-to-write
|
rlm@239
|
91 ;; mode 0x10 : select hi-bit
|
rlm@239
|
92 ;; mode 0x18 : select lo-bit
|
rlm@239
|
93
|
rlm@239
|
94 ;; "output mode"
|
rlm@239
|
95 ;; mode 0x20 : write bytes
|
rlm@239
|
96 ;; mode 0xFF : jump PC
|
rlm@239
|
97
|
rlm@239
|
98
|
rlm@239
|
99 ;; registers
|
rlm@239
|
100 ;; D : mode select
|
rlm@239
|
101 ;; E : count of bytes to write
|
rlm@239
|
102 ;; H : address-high
|
rlm@239
|
103 ;; L : address-low
|
rlm@239
|
104
|
rlm@239
|
105 ;; now A contains the pressed keys
|
rlm@239
|
106 0x2F ; complement A, by request. [D34F]
|
rlm@239
|
107
|
rlm@239
|
108 0x47 ; A->B ;; now B contains the pressed keys
|
rlm@239
|
109 0x7B ; E->A ;; now A contains the count.
|
rlm@239
|
110
|
rlm@239
|
111 0xCB ; test bit 5 of D (are we in o/p mode?)
|
rlm@239
|
112 0x6A
|
rlm@239
|
113 0x28 ; if test == 0, skip this o/p section
|
rlm@239
|
114 0x13 ; JUMP
|
rlm@239
|
115
|
rlm@239
|
116 0xCB ; else, test bit 0 of D (fragile; are we in pc mode?)
|
rlm@239
|
117 0x42
|
rlm@239
|
118 0x28 ; if test == 0, skip the following command
|
rlm@239
|
119 0x01
|
rlm@239
|
120
|
rlm@239
|
121 ;; output mode I: moving the program counter
|
rlm@239
|
122 0xE9 ; ** move PC to (HL)
|
rlm@239
|
123
|
rlm@239
|
124 ;; output mode II: writing bytes
|
rlm@239
|
125 0xFE ; A compare 0. finished writing?
|
rlm@239
|
126 0x00
|
rlm@239
|
127 0x20 ; if we are not finished, skip cleanup
|
rlm@239
|
128 0x04 ; JUMP
|
rlm@239
|
129
|
rlm@239
|
130 ;; CLEANUP
|
rlm@239
|
131 ;; btw, A is already zero.
|
rlm@239
|
132 0xAF ; zero A [D35F]
|
rlm@239
|
133 0x57 ; A->D; makes D=0.
|
rlm@239
|
134 0x18 ; end of frame
|
rlm@239
|
135 0xBC
|
rlm@239
|
136
|
rlm@239
|
137 ;; ---- end of cleanup
|
rlm@239
|
138
|
rlm@239
|
139
|
rlm@239
|
140 ;; continue writing bytes
|
rlm@239
|
141 0x1D ;; decrement E, the number of bytes to write [D363]
|
rlm@239
|
142 0x78 ;; B->A; now A contains the pressed keys
|
rlm@239
|
143 0x77 ;; copy A to (HL)
|
rlm@239
|
144 0x23 ;; increment HL
|
rlm@239
|
145 0x18 ;; end frame. [goto D31F]
|
rlm@239
|
146 0xB6 ;; TODO: set skip length backwards
|
rlm@239
|
147
|
rlm@239
|
148
|
rlm@239
|
149 ;; ---- end of o/p section
|
rlm@239
|
150
|
rlm@239
|
151 ;; i/p mode
|
rlm@239
|
152 ;; adhere to the mode discipline:
|
rlm@239
|
153 ;; D must be one of 0x00 0x08 0x10 0x18.
|
rlm@239
|
154
|
rlm@239
|
155 0x3E ;; load the constant 57 into A. [D369]
|
rlm@239
|
156 0x57
|
rlm@239
|
157 0x82 ;; add the mode to A
|
rlm@239
|
158 0xEA ;; store A into "thing to execute"
|
rlm@239
|
159 0x74
|
rlm@239
|
160 0xD3
|
rlm@239
|
161
|
rlm@239
|
162 0x3E ;; load the constant 8 into A
|
rlm@239
|
163 0x08
|
rlm@239
|
164 0x82 ;; add the mode to A
|
rlm@239
|
165
|
rlm@239
|
166 0x57 ;; store the incremented mode into D
|
rlm@239
|
167 0x78 ;; B->A; now A contains the pressed keys
|
rlm@239
|
168
|
rlm@239
|
169 0x00 ;; var: thing to execute [D374]
|
rlm@239
|
170
|
rlm@239
|
171 0x18 ;; end frame
|
rlm@239
|
172 0xA8])
|
rlm@239
|
173
|
rlm@239
|
174 (defn write-mem-compact []
|
rlm@239
|
175 (-> (tick (mid-game))
|
rlm@239
|
176 (IE! 0)
|
rlm@239
|
177 (inject-item-assembly (write-memory-assembly-compact))))
|
rlm@239
|
178
|
rlm@239
|
179 (defn drive-compact []
|
rlm@239
|
180 (-> (write-mem-compact)
|
rlm@239
|
181 (#(do (println "memory from 0xC00F to 0xC01F:"
|
rlm@239
|
182 (subvec (vec (memory %)) 0xC00F 0xC01F)) %))
|
rlm@239
|
183 (step [])
|
rlm@239
|
184 (step [])
|
rlm@239
|
185 (step [])
|
rlm@239
|
186 (step [:start])
|
rlm@239
|
187 (step [:select])
|
rlm@239
|
188 (step [:u :d])
|
rlm@239
|
189 (step [:a :b :start :select])
|
rlm@239
|
190 (step [:a])
|
rlm@239
|
191 (step [:b])
|
rlm@239
|
192 (step [:a :b])
|
rlm@239
|
193 (step [:select])
|
rlm@239
|
194 (step [])
|
rlm@239
|
195 (step [])
|
rlm@239
|
196 (step [])
|
rlm@239
|
197 (#(do (println "memory from 0xC00F to 0xC01F:"
|
rlm@239
|
198 (subvec (vec (memory %)) 0xC00F 0xC01F)) %))))
|
rlm@239
|
199
|