Mercurial > vba-clojure
comparison clojure/com/aurellem/assembly.clj @ 118:be4ec0e60c16
mode 0 of bootstrapping state machine complete
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 16 Mar 2012 20:03:10 -0500 |
parents | bcb5c41626b4 |
children | 6cbea8ab65b6 |
comparison
equal
deleted
inserted
replaced
117:bcb5c41626b4 | 118:be4ec0e60c16 |
---|---|
39 (defn print-interrupt | 39 (defn print-interrupt |
40 [^SaveState state] | 40 [^SaveState state] |
41 (println (format "IE: %d" (IE state))) | 41 (println (format "IE: %d" (IE state))) |
42 state) | 42 state) |
43 | 43 |
44 (defn print-listing [state begin end] | |
45 (dorun (map | |
46 (fn [opcode line] | |
47 (println (format "0x%04X: 0x%02X" line opcode))) | |
48 (subvec (vec (memory state)) begin end) | |
49 (range begin end))) | |
50 state) | |
51 | |
44 (defn run-assembly | 52 (defn run-assembly |
45 ([info-fn assembly n] | 53 ([info-fn assembly n] |
46 (let [final-state | 54 (let [final-state |
47 (reduce (fn [state _] | 55 (reduce (fn [state _] |
48 (tick (info-fn state))) | 56 (tick (info-fn state))) |
66 (defn view-register [state name reg-fn] | 74 (defn view-register [state name reg-fn] |
67 (println (format "%s: %s" name | 75 (println (format "%s: %s" name |
68 (binary-str (reg-fn state)))) | 76 (binary-str (reg-fn state)))) |
69 state) | 77 state) |
70 | 78 |
71 | |
72 (defn view-memory [state mem] | 79 (defn view-memory [state mem] |
73 (println (format "mem 0x%04X = %s" mem | 80 (println (format "mem 0x%04X = %s" mem |
74 (binary-str (aget (memory state) mem)))) | 81 (binary-str (aget (memory state) mem)))) |
75 state) | 82 state) |
76 | 83 |
84 (defn trace [state] | |
85 (loop [program-counters [] | |
86 opcodes []] | |
87 (let [frame-boundary? | |
88 (com.aurellem.gb.Gb/tick)] | |
89 (println (count opcodes)) | |
90 (if frame-boundary? | |
91 [program-counters opcodes] | |
92 (recur | |
93 (conj program-counters | |
94 (first (registers @current-state))) | |
95 (conj opcodes | |
96 (aget (memory @current-state) | |
97 (PC @current-state)))))))) | |
98 | |
99 (defn good-trace [] | |
100 (-> (mid-game) (tick) (IE! 0) | |
101 (set-inv-mem [0x00 0x00 0X00 0x00]) | |
102 (PC! item-list-start)(print-interrupt) | |
103 (info) (tick) (info) (tick) (info))) | |
104 | |
77 (defn read-down-button [] | 105 (defn read-down-button [] |
78 (-> (tick (mid-game)) | 106 (-> (tick (mid-game)) |
79 (IE! 0) ; disable interrupts | 107 (IE! 0) ; disable interrupts |
80 (inject-item-assembly | 108 (inject-item-assembly |
81 (concat | 109 ;; write 00010000 to 0xFF00 to select joypad |
82 ;; write 00010000 to 0xFF00 to select joypad | 110 [0x18 ;D31D ; jump over |
83 [0x18 ;D31D ; jump over | 111 0x01 ;D31E ; the next 8 bits |
84 0x01 ;D31E ; the next 8 bits | 112 ;D31F |
85 ;D31F | 113 (Integer/parseInt "00100000" 2) ; data section |
86 (Integer/parseInt "00100000" 2) ; data section | 114 |
87 | 115 0xFA ;D320 ; load (D31F) into A |
88 0xFA ;D320 ; load (D31F) into A | 116 0x1F ;D321 --> |
89 0x1F ;D321 --> | 117 0xD3 ;D322 --> D31F |
90 0xD3 ;D322 --> D31F | 118 |
91 | 119 0xEA ;D323 ; load (A), which is |
92 0xEA ;D323 ; load (A), which is | 120 0x00 ;D324 --> ; 00010000, into FF00 |
93 0x00 ;D324 --> ; 00010000, into FF00 | 121 0xFF ;D325 --> FF00 |
94 0xFF ;D325 --> FF00 | 122 |
95 | 123 0x18 ;D326 ; this is the place where |
96 0x18 ;D326 ; this is the place where | 124 0x01 ;D327 ; we will store whether |
97 0x01 ;D327 ; we will store whether | 125 0x00 ;D328 ; "down" is pressed. |
98 0x00 ;D328 ; "down" is pressed. | 126 |
99 | 127 0xFA ;D329 ; (FF00) -> A |
100 0xFA ;D329 ; (FF00) -> A | 128 0x00 ;D32A |
101 0x00 ;D32A | 129 0xFF ;D32B |
102 0xFF ;D32B | 130 |
103 | 131 0xCB ;D32C ; Test whether "down" |
104 0xCB ;D32C ; Test whether "down" | 132 0x5F ;D32D ; is pressed. |
105 0x5F ;D32D ; is pressed. | 133 |
106 | 134 0x28 ;D32E ; if down is pressed, |
107 0x28 ;D32E ; if down is pressed, | 135 0x03 ;D32F ; skip the next section |
108 0x03 ;D32F ; skip the next section | 136 ; of code. |
109 ; of code. | 137 ;; down-is-not-pressed |
110 ;; down-is-not-pressed | 138 0xC3 ;D330 |
111 0xC3 ;D330 | 139 0x1D ;D331 ; return to beginning |
112 0x1D ;D331 ; return to beginning | 140 0xD3 ;D332 |
113 0xD3 ;D332 | 141 |
114 | 142 ;; down-is-pressed |
115 ;; down-is-pressed | 143 0xEA ;D334 ; write A to D328 if |
116 0xEA ;D334 ; write A to D328 if | 144 0x28 ;D335 ; "down" was pressed |
117 0x28 ;D335 ; "down" was pressed | 145 0xD3 ;D336 |
118 0xD3 ;D336 | 146 |
119 | 147 0xC3 ;D330 |
120 0xC3 ;D330 | 148 0x1D ;D331 ; return to beginning |
121 0x1D ;D331 ; return to beginning | 149 0xD3 ;D332 |
122 0xD3 ;D332 | 150 ]))) |
123 ] | 151 |
124 | 152 (defn test-read-down [] |
125 [])))) | 153 (= (view-memory (step (step (read-down-button) [:d])) 0xD328) |
126 | 154 (view-memory (step (step (read-down-button))) 0xD328))) |
127 | |
128 | |
129 | 155 |
130 (defn count-frames [] | 156 (defn count-frames [] |
131 (-> (tick (mid-game)) | 157 (-> (tick (mid-game)) |
132 (IE! 0) ; disable interrupts | 158 (IE! 0) ; disable interrupts |
133 (inject-item-assembly | 159 (inject-item-assembly |
204 0xD3 ;D348 | 230 0xD3 ;D348 |
205 | 231 |
206 0xC3 ;D349 ; return to beginning | 232 0xC3 ;D349 ; return to beginning |
207 0x1D ;D34A | 233 0x1D ;D34A |
208 0xD3 ;D34B | 234 0xD3 ;D34B |
209 | |
210 ]))) | 235 ]))) |
211 | 236 |
212 (defn step-count-frames [] | 237 (defn step-count-frames [] |
213 (-> (read-down-button) | 238 (-> (read-down-button) |
214 (info) | 239 (info) |
233 (tick) | 258 (tick) |
234 (info) | 259 (info) |
235 (tick) | 260 (tick) |
236 (print-inventory))) | 261 (print-inventory))) |
237 | 262 |
238 ;;(defn test-read-down [] | |
239 ;; (= (view-memory (step (step (read-buttons) [:d])) 0xD328) | |
240 ;; (view-memory (step (step (read-buttons))) 0xD328))) | |
241 | |
242 (defn test-count-frames [] | 263 (defn test-count-frames [] |
243 (= 255 (aget (memory ((apply comp (repeat 255 step)) | 264 (= 255 (aget (memory ((apply comp (repeat 255 step)) |
244 (count-frames))) | 265 (count-frames))) |
245 0xD31F))) | 266 0xD31F))) |
246 | |
247 | |
248 (defn trace [state] | |
249 (loop [program-counters [] | |
250 opcodes []] | |
251 (let [frame-boundary? | |
252 (com.aurellem.gb.Gb/tick)] | |
253 (println (count opcodes)) | |
254 (if frame-boundary? | |
255 [program-counters opcodes] | |
256 (recur | |
257 (conj program-counters | |
258 (first (registers @current-state))) | |
259 (conj opcodes | |
260 (aget (memory @current-state) | |
261 (PC @current-state)))))))) | |
262 | |
263 (defn good-trace [] | |
264 (-> (mid-game) (tick) (IE! 0) | |
265 (set-inv-mem [0x00 0x00 0X00 0x00]) | |
266 (PC! item-list-start)(print-interrupt) | |
267 (info) (tick) (info) (tick) (info))) | |
268 | 267 |
269 ;; specs for main bootstrap program | 268 ;; specs for main bootstrap program |
270 ;; starts in "mode-select" mode | 269 ;; starts in "mode-select" mode |
271 ;; Each button press takes place in a single frame. | 270 ;; Each button press takes place in a single frame. |
272 ;; mode-select-mode takes one of the main buttons | 271 ;; mode-select-mode takes one of the main buttons |
284 ;; written, starting at the start position. | 283 ;; written, starting at the start position. |
285 | 284 |
286 ;; then, the actual bytes are entered and are written to the | 285 ;; then, the actual bytes are entered and are written to the |
287 ;; start address in sequence. | 286 ;; start address in sequence. |
288 | 287 |
289 | 288 (defn input-number-assembly [] |
289 [0x18 ;D31D ; jump over | |
290 0x02 ;D31E ; the next 2 bytes | |
291 0x00 ;D31F ; frame-count | |
292 0x00 ;D320 ; v-blank-prev | |
293 | |
294 0xFA ;D321 | |
295 0x41 ;D322 ; load (FF41) into A | |
296 0xFF ;D323 ; this contains mode flags | |
297 | |
298 ;; if we're in v-blank, the bit-1 is 0 | |
299 ;; and bit-2 is 1 Otherwise, it is not v-blank. | |
300 0xCB ;D324 ; test bit-1 of A | |
301 0x4F ;D325 | |
302 | |
303 0xC2 ;D326 ; if bit-1 is not 0 | |
304 0x44 ;D327 ; GOTO not-v-blank | |
305 0xD3 ;D328 | |
306 | |
307 0xCB ;D329 ; test bit-0 of A | |
308 0x47 ;D32A | |
309 | |
310 0xCA ;D32B ; if bit-0 is not 1 | |
311 0x44 ;D32C ; GOTO not-v-blank | |
312 0xD3 ;D32D | |
313 | |
314 ;;; in v-blank mode | |
315 | |
316 ;; if v-blank-prev was 0, | |
317 ;; increment frame-count | |
318 | |
319 0xFA ;D32E ; load v-blank-prev to A | |
320 0x20 ;D32F | |
321 0xD3 ;D330 | |
322 | |
323 0xCB ;D331 | |
324 0x47 ;D332 ; test bit-0 of A | |
325 | |
326 0x20 ;D333 ; skip next section | |
327 0x07 ;D334 ; if v-blank-prev was not zero | |
328 | |
329 ;; v-blank was 0, increment frame-count | |
330 0xFA ;D335 ; load frame-count into A | |
331 0x1F ;D336 | |
332 0xD3 ;D337 | |
333 | |
334 0x3C ;D338 ; inc A | |
335 | |
336 0xEA ;D339 ; load A into frame-count | |
337 0x1F ;D33A | |
338 0xD3 ;D33B | |
339 | |
340 ;; set v-blank-prev to 1 | |
341 0x3E ;D33C ; load 1 into A | |
342 0x01 ;D33D | |
343 | |
344 0xEA ;D33E ; load A into v-blank-prev | |
345 0x20 ;D33F | |
346 0xD3 ;D340 | |
347 | |
348 0xC3 ;D341 ; GOTO input handling code | |
349 0x4E ;D342 | |
350 0xD3 ;D343 | |
351 | |
352 ;;; not in v-blank mode | |
353 ;; set v-blank-prev to 0 | |
354 0x3E ;D344 ; load 0 into A | |
355 0x00 ;D345 | |
356 | |
357 0xEA ;D346 ; load A into v-blank-prev | |
358 0x20 ;D347 | |
359 0xD3 ;D348 | |
360 | |
361 0xC3 ;D349 ; return to beginning | |
362 0x1D ;D34A | |
363 0xD3 ;D34B | |
364 | |
365 0x00 ;D34C ; these are here | |
366 0x00 ;D34D ; for glue | |
367 | |
368 | |
369 ;;; calculate input number based on button presses | |
370 0x18 ;D34E ; skip next 3 bytes | |
371 0x03 ;D34F | |
372 ;D350 | |
373 (Integer/parseInt "00100000" 2) ; select directional pad | |
374 ;D351 | |
375 (Integer/parseInt "00010000" 2) ; select buttons | |
376 0x00 ;D352 ; input-number | |
377 | |
378 ;; select directional pad, store low bits in B | |
379 | |
380 0xFA ;D353 ; load (D350) into A | |
381 0x50 ;D354 --> | |
382 0xD3 ;D355 --> D31F | |
383 | |
384 0xEA ;D356 ; load (A), which is | |
385 0x00 ;D357 --> ; 00010000, into FF00 | |
386 0xFF ;D358 --> FF00 | |
387 | |
388 0x06 ;D359 | |
389 ;D35A | |
390 (Integer/parseInt "11110000" 2) ; "11110000" -> B | |
391 0xFA ;D35B ; (FF00) -> A | |
392 0x00 ;D35C | |
393 0xFF ;D35D | |
394 | |
395 0xCB ;D35E ; swap nybbles on A | |
396 0x37 ;D35F | |
397 0xA0 ;D360 ; (AND A B) -> A | |
398 0x47 ;D361 ; A -> B | |
399 | |
400 ;; select buttons store bottom bits in C | |
401 | |
402 0xFA ; ; load (D351) into A | |
403 0x51 ; --> | |
404 0xD3 ; --> D31F | |
405 | |
406 0xEA ; ; load (A), which is | |
407 0x00 ; --> ; 00001000, into FF00 | |
408 0xFF ; --> FF00 | |
409 | |
410 0x0E ; | |
411 (Integer/parseInt "00001111" 2) ; "00001111" -> C | |
412 | |
413 0xFA ; ; (FF00) -> A | |
414 0x00 ; | |
415 0xFF ; | |
416 | |
417 0xA1 ; ; (AND A C) -> A | |
418 0x4F ; ; A -> C | |
419 | |
420 ;; combine the B and C registers into the input number | |
421 0x79 ; ; C -> A | |
422 0xB0 ; ; (OR A B) -> A | |
423 0x2F ; ; negate A | |
424 | |
425 0xEA ; ; store A into input-number | |
426 0x52 ; | |
427 0xD3 ; | |
428 | |
429 0xC3 ; ; return to beginning | |
430 0x1D ; | |
431 0xD3 ; | |
432 ]) | |
290 | 433 |
291 (defn input-number [] | 434 (defn input-number [] |
292 (-> (tick (mid-game)) | 435 (-> (tick (mid-game)) |
293 (IE! 0) ; disable interrupts | 436 (IE! 0) ; disable interrupts |
294 (inject-item-assembly | 437 (inject-item-assembly (input-number-assembly)))) |
295 [0x18 ;D31D ; jump over | |
296 0x02 ;D31E ; the next 2 bytes | |
297 0x00 ;D31F ; frame-count | |
298 0x00 ;D320 ; v-blank-prev | |
299 | |
300 0xFA ;D321 | |
301 0x41 ;D322 ; load (FF41) into A | |
302 0xFF ;D323 ; this contains mode flags | |
303 | |
304 ;; if we're in v-blank, the bit-1 is 0 | |
305 ;; and bit-2 is 1 Otherwise, it is not v-blank. | |
306 0xCB ;D324 ; test bit-1 of A | |
307 0x4F ;D325 | |
308 | |
309 0xC2 ;D326 ; if bit-1 is not 0 | |
310 0x44 ;D327 ; GOTO not-v-blank | |
311 0xD3 ;D328 | |
312 | |
313 0xCB ;D329 ; test bit-0 of A | |
314 0x47 ;D32A | |
315 | |
316 0xCA ;D32B ; if bit-0 is not 1 | |
317 0x44 ;D32C ; GOTO not-v-blank | |
318 0xD3 ;D32D | |
319 | |
320 ;;; in v-blank mode | |
321 | |
322 ;; if v-blank-prev was 0, | |
323 ;; increment frame-count | |
324 | |
325 0xFA ;D32E ; load v-blank-prev to A | |
326 0x20 ;D32F | |
327 0xD3 ;D330 | |
328 | |
329 0xCB ;D331 | |
330 0x47 ;D332 ; test bit-0 of A | |
331 | |
332 0x20 ;D333 ; skip next section | |
333 0x07 ;D334 ; if v-blank-prev was not zero | |
334 | |
335 ;; v-blank was 0, increment frame-count | |
336 0xFA ;D335 ; load frame-count into A | |
337 0x1F ;D336 | |
338 0xD3 ;D337 | |
339 | |
340 0x3C ;D338 ; inc A | |
341 | |
342 0xEA ;D339 ; load A into frame-count | |
343 0x1F ;D33A | |
344 0xD3 ;D33B | |
345 | |
346 ;; set v-blank-prev to 1 | |
347 0x3E ;D33C ; load 1 into A | |
348 0x01 ;D33D | |
349 | |
350 0xEA ;D33E ; load A into v-blank-prev | |
351 0x20 ;D33F | |
352 0xD3 ;D340 | |
353 | |
354 0xC3 ;D341 ; GOTO input handling code | |
355 0x4E ;D342 | |
356 0xD3 ;D343 | |
357 | |
358 ;;; not in v-blank mode | |
359 ;; set v-blank-prev to 0 | |
360 0x3E ;D344 ; load 0 into A | |
361 0x00 ;D345 | |
362 | |
363 0xEA ;D346 ; load A into v-blank-prev | |
364 0x20 ;D347 | |
365 0xD3 ;D348 | |
366 | |
367 0xC3 ;D349 ; return to beginning | |
368 0x1D ;D34A | |
369 0xD3 ;D34B | |
370 | |
371 0x00 ;D34C ; these are here | |
372 0x00 ;D34D ; for glue | |
373 | |
374 | |
375 ;;; calculate input number based on button presses | |
376 0x18 ;D34E ; skip next 3 bytes | |
377 0x03 ;D34F | |
378 ;D350 | |
379 (Integer/parseInt "00100000" 2) ; select directional pad | |
380 ;D351 | |
381 (Integer/parseInt "00010000" 2) ; select buttons | |
382 0x00 ;D352 ; input-number | |
383 | |
384 ;; select directional pad, store low bits in B | |
385 | |
386 0xFA ;D353 ; load (D350) into A | |
387 0x50 ;D354 --> | |
388 0xD3 ;D355 --> D31F | |
389 | |
390 0xEA ;D356 ; load (A), which is | |
391 0x00 ;D357 --> ; 00010000, into FF00 | |
392 0xFF ;D358 --> FF00 | |
393 | |
394 0x06 ;D359 | |
395 ;D35A | |
396 (Integer/parseInt "11110000" 2) ; "11110000" -> B | |
397 0xFA ;D35B ; (FF00) -> A | |
398 0x00 ;D35C | |
399 0xFF ;D35D | |
400 | |
401 0xCB ;D35E ; swap nybbles on A | |
402 0x37 ;D35F | |
403 0xA0 ;D360 ; (AND A B) -> A | |
404 0x47 ;D361 ; A -> B | |
405 | |
406 ;; select buttons store bottom bits in C | |
407 | |
408 0xFA ; ; load (D351) into A | |
409 0x51 ; --> | |
410 0xD3 ; --> D31F | |
411 | |
412 0xEA ; ; load (A), which is | |
413 0x00 ; --> ; 00001000, into FF00 | |
414 0xFF ; --> FF00 | |
415 | |
416 0x0E ; | |
417 (Integer/parseInt "00001111" 2) ; "00001111" -> C | |
418 | |
419 0xFA ; ; (FF00) -> A | |
420 0x00 ; | |
421 0xFF ; | |
422 | |
423 0xA1 ; ; (AND A C) -> A | |
424 0x4F ; ; A -> C | |
425 | |
426 | |
427 ;; combine the B and C registers into the input number | |
428 0x79 ; ; C -> A | |
429 0xB0 ; ; (OR A B) -> A | |
430 0x2F ; ; negate A | |
431 | |
432 0xEA ; ; store A into input-number | |
433 0x52 ; | |
434 0xD3 ; | |
435 | |
436 0xC3 ; ; return to beginning | |
437 0x1D ; | |
438 0xD3 ; | |
439 ]))) | |
440 | |
441 (defn print-listing [state begin end] | |
442 (dorun (map | |
443 (fn [opcode line] | |
444 (println (format "0x%04X: 0x%02X" line opcode))) | |
445 (subvec (vec (memory state)) begin end) | |
446 (range begin end))) | |
447 state) | |
448 | 438 |
449 (defn test-input-number | 439 (defn test-input-number |
450 "Input freestyle buttons and observe the effects at the repl." | 440 "Input freestyle buttons and observe the effects at the repl." |
451 [] | 441 [] |
452 (set-state! (input-number)) | 442 (set-state! (input-number)) |
453 (dotimes [_ 90000] (step (view-memory @current-state 0xD352)))) | 443 (dotimes [_ 90000] (step (view-memory @current-state 0xD352)))) |
454 | 444 |
455 | 445 (defn write-memory-assembly [] |
456 | 446 [0x18 ;D31D ; jump over |
457 | 447 0x02 ;D31E ; the next 2 bytes |
448 0x00 ;D31F ; frame-count | |
449 0x00 ;D320 ; v-blank-prev | |
450 | |
451 0xFA ;D321 | |
452 0x41 ;D322 ; load (FF41) into A | |
453 0xFF ;D323 ; this contains mode flags | |
454 | |
455 ;; if we're in v-blank, the bit-1 is 0 | |
456 ;; and bit-2 is 1 Otherwise, it is not v-blank. | |
457 0xCB ;D324 ; test bit-1 of A | |
458 0x4F ;D325 | |
459 | |
460 0xC2 ;D326 ; if bit-1 is not 0 | |
461 0x44 ;D327 ; GOTO not-v-blank | |
462 0xD3 ;D328 | |
463 | |
464 0xCB ;D329 ; test bit-0 of A | |
465 0x47 ;D32A | |
466 | |
467 0xCA ;D32B ; if bit-0 is not 1 | |
468 0x44 ;D32C ; GOTO not-v-blank | |
469 0xD3 ;D32D | |
470 | |
471 ;;; in v-blank mode | |
472 | |
473 ;; if v-blank-prev was 0, | |
474 ;; increment frame-count | |
475 | |
476 0xFA ;D32E ; load v-blank-prev to A | |
477 0x20 ;D32F | |
478 0xD3 ;D330 | |
479 | |
480 0xCB ;D331 | |
481 0x47 ;D332 ; test bit-0 of A | |
482 | |
483 0x20 ;D333 ; skip next section | |
484 0x07 ;D334 ; if v-blank-prev was not zero | |
485 | |
486 ;; v-blank was 0, increment frame-count | |
487 0xFA ;D335 ; load frame-count into A | |
488 0x1F ;D336 | |
489 0xD3 ;D337 | |
490 | |
491 0x3C ;D338 ; inc A | |
492 | |
493 0xEA ;D339 ; load A into frame-count | |
494 0x1F ;D33A | |
495 0xD3 ;D33B | |
496 | |
497 ;; set v-blank-prev to 1 | |
498 0x3E ;D33C ; load 1 into A | |
499 0x01 ;D33D | |
500 | |
501 0xEA ;D33E ; load A into v-blank-prev | |
502 0x20 ;D33F | |
503 0xD3 ;D340 | |
504 | |
505 0xC3 ;D341 ; GOTO input handling code | |
506 0x4E ;D342 | |
507 0xD3 ;D343 | |
508 | |
509 ;;; not in v-blank mode | |
510 ;; set v-blank-prev to 0 | |
511 0x3E ;D344 ; load 0 into A | |
512 0x00 ;D345 | |
513 | |
514 0xEA ;D346 ; load A into v-blank-prev | |
515 0x20 ;D347 | |
516 0xD3 ;D348 | |
517 | |
518 0xC3 ;D349 ; return to beginning | |
519 0x1D ;D34A | |
520 0xD3 ;D34B | |
521 | |
522 0x00 ;D34C ; these are here | |
523 0x00 ;D34D ; for glue | |
524 | |
525 | |
526 ;;; calculate input number based on button presses | |
527 0x18 ;D34E ; skip next 3 bytes | |
528 0x03 ;D34F | |
529 ;D350 | |
530 (Integer/parseInt "00100000" 2) ; select directional pad | |
531 ;D351 | |
532 (Integer/parseInt "00010000" 2) ; select buttons | |
533 0x00 ;D352 ; input-number | |
534 | |
535 ;; select directional pad, store low bits in B | |
536 | |
537 0xFA ;D353 ; load (D350) into A | |
538 0x50 ;D354 --> | |
539 0xD3 ;D355 --> D31F | |
540 | |
541 0xEA ;D356 ; load (A), which is | |
542 0x00 ;D357 --> ; 00010000, into FF00 | |
543 0xFF ;D358 --> FF00 | |
544 | |
545 0x06 ;D359 | |
546 ;D35A | |
547 (Integer/parseInt "11110000" 2) ; "11110000" -> B | |
548 0xFA ;D35B ; (FF00) -> A | |
549 0x00 ;D35C | |
550 0xFF ;D35D | |
551 | |
552 0xCB ;D35E ; swap nybbles on A | |
553 0x37 ;D35F | |
554 0xA0 ;D360 ; (AND A B) -> A | |
555 0x47 ;D361 ; A -> B | |
556 | |
557 ;; select buttons store bottom bits in C | |
558 | |
559 0xFA ;D362 ; load (D351) into A | |
560 0x51 ;D363 --> | |
561 0xD3 ;D364 --> D31F | |
562 | |
563 0xEA ;D365 ; load (A), which is | |
564 0x00 ;D366 --> ; 00001000, into FF00 | |
565 0xFF ;D367 --> FF00 | |
566 | |
567 0x0E ;D368 | |
568 ;D369 | |
569 (Integer/parseInt "00001111" 2) ; "00001111" -> C | |
570 | |
571 0xFA ;D36A ; (FF00) -> A | |
572 0x00 ;D36B | |
573 0xFF ;D36C | |
574 | |
575 0xA1 ;D36D ; (AND A C) -> A | |
576 0x4F ;D36E ; A -> C | |
577 | |
578 ;; combine the B and C registers into the input number | |
579 0x79 ;D36F ; C -> A | |
580 0xB0 ;D370 ; (OR A B) -> A | |
581 0x2F ;D371 ; negate A | |
582 | |
583 0xEA ;D372 ; store A into input-number | |
584 0x52 ;D373 | |
585 0xD3 ;D374 | |
586 | |
587 0xC3 ;D375 ; GOTO state machine | |
588 ;;0x1D | |
589 0x80 ;D376 | |
590 0xD3 ;D377 | |
591 | |
592 0x00 ;D378 | |
593 0x00 ;D379 | |
594 0x00 ;D37A | |
595 0x00 ;D37B ; these are here because | |
596 0x00 ;D37C ; I messed up :( | |
597 0x00 ;D37D | |
598 0x00 ;D37E | |
599 0x00 ;D37F | |
600 | |
601 ;; beginning of main state machine | |
602 0x18 ;D380 ; Declaration of variables | |
603 0x05 ;D381 ; 5 variables: | |
604 0x00 ;D382 ; current-mode | |
605 0x00 ;D383 ; bytes-left-to-write | |
606 0x00 ;D384 ; unused | |
607 0x00 ;D385 ; unused | |
608 0x00 ;D386 ; unused | |
609 | |
610 | |
611 ;; banch on current mode | |
612 ;; mode 0 -- input-mode mode | |
613 ;; means that we are waiting for a mode, so set the mode to | |
614 ;; whatever is currently in input number. If nothing is | |
615 ;; entered, then the program stays in input-mode mode | |
616 | |
617 0xFA ;D387 ; load current-mode (0xD382) | |
618 0x82 ;D388 ; into A | |
619 0xD3 ;D389 | |
620 | |
621 0x00 ;D38A | |
622 | |
623 0xFE ;D38B | |
624 0x00 ;D38C ; compare A with 0x00 | |
625 | |
626 ;; TODO make this jump non-absolute | |
627 | |
628 0xCA ;D38D ; GOTO Mode 0 if current-mode is 0 | |
629 0xA8 ;D38E | |
630 0xD3 ;D38F | |
631 | |
632 0x00 ;D390 | |
633 0x00 ;D391 | |
634 0x00 ;D392 | |
635 0x00 ;D393 | |
636 0x00 ;D394 | |
637 0x00 ;D395 | |
638 0x00 ;D396 | |
639 0x00 ;D397 | |
640 0x00 ;D398 | |
641 0x00 ;D399 | |
642 0x00 ;D39A | |
643 0x00 ;D39B | |
644 0x00 ;D39C | |
645 0x00 ;D39D | |
646 0x00 ;D39E | |
647 0x00 ;D39F | |
648 0x00 ;D3A0 | |
649 0x00 ;D3A1 | |
650 0x00 ;D3A2 | |
651 0x00 ;D3A3 | |
652 0x00 ;D3A4 | |
653 ;; End of Mode checking, goto beginning | |
654 0xC3 ;D3A5 | |
655 0x1D ;D3A6 | |
656 0xD3 ;D3A7 | |
657 ;; Mode 0 | |
658 ;; set current-mode to input-number | |
659 0xFA ;D3A8 ; load input-number (0xD352) | |
660 0x52 ;D3A9 ; into A | |
661 0xD3 ;D3AA | |
662 | |
663 0xEA ;D3AB ; load A into current-mode | |
664 0x82 ;D3AC ; (0xD382) | |
665 0xD3 ;D3AD | |
666 | |
667 0xC3 ;D3AE ; go back to beginning | |
668 0x1D ;D3AF | |
669 0xD3 ;D3B0 | |
670 | |
671 0x00 ;D3B1 | |
672 0x00 ;D3B2 | |
673 0x00 ;D3B3 | |
674 0x00 ;D3B4 | |
675 0x00 ;D3B5 | |
676 0x00 ;D3B6 | |
677 0x00 ;D3B7 | |
678 0x00 ;D3B8 | |
679 0x00 ;D3B9 | |
680 0x00 ;D3BA | |
681 0x00 ;D3BB | |
682 0x00 ;D3BC | |
683 0x00 ;D3BD | |
684 0x00 ;D3BE | |
685 0x00 ;D3BF | |
686 0x00 ;D3C0 | |
687 0x00 ;D3C1 | |
688 0x00 ;D3C2 | |
689 0x00 ;D3C3 | |
690 0x00 ;D3C4 | |
691 0x00 ;D3C5 | |
692 0x00 ;D3C6 | |
693 0x00 ;D3C7 | |
694 0x00 ;D3C8 | |
695 0x00 ;D3C9 | |
696 0x00 ;D3CA | |
697 0x00 ;D3CB | |
698 0x00 ;D3CC | |
699 0x00 ;D3CD | |
700 0x00 ;D3CE | |
701 0x00 ;D3CF | |
702 0x00 ;D3D0 | |
703 0x00 ;D3D1 | |
704 0x00 ;D3D2 | |
705 0x00 ;D3D3 | |
706 0x00 ;D3D4 | |
707 0x00 ;D3D5 | |
708 0x00 ;D3D6 | |
709 | |
710 | |
711 | |
712 | |
713 0xC3 ; ; Complete Loop | |
714 0x1D ; | |
715 0xD3 ; | |
716 | |
717 | |
718 | |
719 ]) | |
720 | |
721 | |
722 (def frame-count 0xD31F) | |
723 (def input 0xD352) | |
724 (def current-mode 0xD382) | |
725 | |
726 (defn write-memory [] | |
727 (-> (tick (mid-game)) | |
728 (IE! 0) ; disable interrupts | |
729 (inject-item-assembly (write-memory-assembly)))) |