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))))