comparison clojure/com/aurellem/gb/rlm_assembly.clj @ 416:21b8b3350b20

everything works :) now I have total control over the game.
author Robert McIntyre <rlm@mit.edu>
date Sat, 14 Apr 2012 05:41:55 -0500
parents f2f1e0b8c1c7
children 9068685e7d96
comparison
equal deleted inserted replaced
415:f2f1e0b8c1c7 416:21b8b3350b20
222 222
223 (defn ->signed-8-bit [n] 223 (defn ->signed-8-bit [n]
224 (if (< n 0) 224 (if (< n 0)
225 (+ 256 n) n)) 225 (+ 256 n) n))
226 226
227 (defn frame-metronome** [] 227 (defn frame-metronome []
228 (let [init [0xC5] ;; save value of BC 228 (let [init [0xC5] ;; save value of BC
229 timing-loop 229 timing-loop
230 [0x01 ; \ 230 [0x01 ; \
231 0x43 ; | 231 0x43 ; |
232 0xFE ; | load 0xFF44 into BC without repeats 232 0xFE ; | load 0xFF44 into BC without repeats
245 0xFD]] 245 0xFD]]
246 (concat init timing-loop continue-if-144 spin-loop))) 246 (concat init timing-loop continue-if-144 spin-loop)))
247 247
248 (defn frame-metronome* [] 248 (defn frame-metronome* []
249 [0x3E ;; smallest version, but uses repeated nybbles 249 [0x3E ;; smallest version, but uses repeated nybbles
250 0x01 250 0x01
251 0xE0 251 0xE0
252 0xFF]) 252 0xFF])
253 253
254 254 (defn frame-metronome** []
255 (defn frame-metronome []
256 [0x06 ;; load 0xFE into B 255 [0x06 ;; load 0xFE into B
257 0xFE 256 0xFE
258 0x04 ;; inc B, now B == FF 257 0x04 ;; inc B, now B == FF
259 0x3E 258
259 0x3E ;; RLM-debug
260 0x01 ;; 1->A 260 0x01 ;; 1->A
261 261
262 0x48 ;; B->C 262 0x48 ;; B->C
263 0x02]) ;; A->(BC) set exclusive v-blank interrupt 263 0x02]) ;; A->(BC) set exclusive v-blank interrupt
264 264
265 (defn test-frame-metronome 265 (defn test-frame-metronome
266 "Ensure that frame-metronome ticks exactly once every frame." 266 "Ensure that frame-metronome ticks exactly once every frame."
267 ([] (test-frame-metronome 151)) 267 ([] (test-frame-metronome 151))
268 ([steps] 268 ([steps]
269 (let [inc-E [0x1C 0x76 0x18 269 (let [inc-E [0x1C 0x18
270 (->signed-8-bit -4)] 270 (->signed-8-bit
271 (+ -3
272 (-(count (frame-metronome)))))]
271 273
272 program (concat (frame-metronome) inc-E) 274 program (concat (frame-metronome) inc-E)
273 count-frames 275 count-frames
274 (-> (tick (mid-game)) 276 (-> (tick (mid-game))
275 (IE! 0) 277 (IE! 0)
282 (assert (= steps E-after-moves)) 284 (assert (= steps E-after-moves))
283 (println "frame-count test passed.") 285 (println "frame-count test passed.")
284 count-frames))) 286 count-frames)))
285 287
286 (defn read-user-input [] 288 (defn read-user-input []
287 [0xAF 0x4F 0x47 ;; 0->A; 0->C; 0->B 289 [0x3E
288 0xC5 ;; save value of BC
289
290 0x3E
291 0x20 ; prepare to measure d-pad 290 0x20 ; prepare to measure d-pad
292 291
293 0x3F ; clear carry flag no-op to prevent repeated nybbles 292 0x3F ; clear carry flag no-op to prevent repeated nybbles
294 293
295 0x01 ;\ 294 0x01 ;\
376 ;; JUMP 0xE9 ;; jump to (HL) 375 ;; JUMP 0xE9 ;; jump to (HL)
377 376
378 ;; multi-action-modes 377 ;; multi-action-modes
379 ;; WRITE 0x47 ;; A->B 378 ;; WRITE 0x47 ;; A->B
380 379
381 (let [header (concat (frame-metronome) (read-user-input)) 380 (let [init [0xAF 0x4F 0x47] ;; 0->A; 0->C; 0->B
381 header (concat (frame-metronome) (read-user-input))
382 382
383 input 383 input
384 [0xC1 ;; pop BC so it's not volatile 384 [0xC1 ;; pop BC so it's not volatile
385 385
386 0x5F ;; A->E 386 0x5F ;; A->E
407 :to-be-executed-address 407 :to-be-executed-address
408 408
409 0x7B ;; E->A 409 0x7B ;; E->A
410 0x4F ;; A->C now C stores previous instruction 410 0x4F ;; A->C now C stores previous instruction
411 0x18 ;; return 411 0x18 ;; return
412 :to-halt] 412 :to-jump]
413 413
414 output 414 output
415 [:output-start ;; just a label 415 [:output-start ;; just a label
416 0x3F ;; ;; prevent repeated nybbles 416 0x3F ;; ;; prevent repeated nybbles
417 0x54 ;; 417 0x54 ;;
421 ;; / any repeating nybbles 421 ;; / any repeating nybbles
422 0x05 ;; DEC bytes-to-write (B) 422 0x05 ;; DEC bytes-to-write (B)
423 423
424 0x23 ;; inc HL 424 0x23 ;; inc HL
425 425
426 0x76 ;; HALT, peasant!
427 0x18 426 0x18
428 :to-beginning] 427 :to-beginning]
429 428
430 symbols 429 symbols
431 {:to-be-executed-address 430 {:to-be-executed-address
432 (reverse 431 (reverse
433 (disect-bytes-2 432 (disect-bytes-2
434 (+ start-address 433 (+ start-address
435 (count header) 434 (count header)
435 (count init)
436 (symbol-index :to-be-executed input)))) 436 (symbol-index :to-be-executed input))))
437 :to-be-executed 0x3F} ;; clear carry flag no-op 437 :to-be-executed 0x3F} ;; clear carry flag no-op
438 438
439 program** (flatten 439 program** (flatten
440 (replace symbols (concat header input output))) 440 (replace
441 symbols
442 (concat init header input output)))
441 443
442 resolve-internal-jumps 444 resolve-internal-jumps
443 {:output-start [] 445 {:output-start []
444 :to-output 446 :to-output
445 (->signed-8-bit 447 (->signed-8-bit
449 451
450 program* 452 program*
451 (flatten (replace resolve-internal-jumps program**)) 453 (flatten (replace resolve-internal-jumps program**))
452 454
453 resolve-external-jumps 455 resolve-external-jumps
454 {:to-halt 456 {:to-jump
455 (- (- (symbol-index :to-beginning program*) 457 (- (- (symbol-index :to-beginning program*)
456 (symbol-index :to-halt program*)) 3) 458 (symbol-index :to-jump program*)) 2)
457 459
458 :to-beginning 460 :to-beginning
459 (->signed-8-bit 461 (->signed-8-bit
460 (+ 2 (count (frame-metronome)) 462 (+ (count init) -1
461 (- (symbol-index :to-beginning program*))))} 463 (- (symbol-index :to-beginning program*))))}
462 464
463 program 465 program
464 (replace resolve-external-jumps program*)] 466 (replace resolve-external-jumps program*)]
465 program))) 467 program)))