Mercurial > vba-clojure
diff 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 |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/assembly.clj Fri Mar 16 17:50:35 2012 -0500 1.2 +++ b/clojure/com/aurellem/assembly.clj Fri Mar 16 20:03:10 2012 -0500 1.3 @@ -41,6 +41,14 @@ 1.4 (println (format "IE: %d" (IE state))) 1.5 state) 1.6 1.7 +(defn print-listing [state begin end] 1.8 + (dorun (map 1.9 + (fn [opcode line] 1.10 + (println (format "0x%04X: 0x%02X" line opcode))) 1.11 + (subvec (vec (memory state)) begin end) 1.12 + (range begin end))) 1.13 + state) 1.14 + 1.15 (defn run-assembly 1.16 ([info-fn assembly n] 1.17 (let [final-state 1.18 @@ -68,64 +76,82 @@ 1.19 (binary-str (reg-fn state)))) 1.20 state) 1.21 1.22 - 1.23 (defn view-memory [state mem] 1.24 (println (format "mem 0x%04X = %s" mem 1.25 (binary-str (aget (memory state) mem)))) 1.26 state) 1.27 1.28 +(defn trace [state] 1.29 + (loop [program-counters [] 1.30 + opcodes []] 1.31 + (let [frame-boundary? 1.32 + (com.aurellem.gb.Gb/tick)] 1.33 + (println (count opcodes)) 1.34 + (if frame-boundary? 1.35 + [program-counters opcodes] 1.36 + (recur 1.37 + (conj program-counters 1.38 + (first (registers @current-state))) 1.39 + (conj opcodes 1.40 + (aget (memory @current-state) 1.41 + (PC @current-state)))))))) 1.42 + 1.43 +(defn good-trace [] 1.44 + (-> (mid-game) (tick) (IE! 0) 1.45 + (set-inv-mem [0x00 0x00 0X00 0x00]) 1.46 + (PC! item-list-start)(print-interrupt) 1.47 + (info) (tick) (info) (tick) (info))) 1.48 + 1.49 (defn read-down-button [] 1.50 (-> (tick (mid-game)) 1.51 (IE! 0) ; disable interrupts 1.52 (inject-item-assembly 1.53 - (concat 1.54 - ;; write 00010000 to 0xFF00 to select joypad 1.55 - [0x18 ;D31D ; jump over 1.56 - 0x01 ;D31E ; the next 8 bits 1.57 - ;D31F 1.58 - (Integer/parseInt "00100000" 2) ; data section 1.59 - 1.60 - 0xFA ;D320 ; load (D31F) into A 1.61 - 0x1F ;D321 --> 1.62 - 0xD3 ;D322 --> D31F 1.63 + ;; write 00010000 to 0xFF00 to select joypad 1.64 + [0x18 ;D31D ; jump over 1.65 + 0x01 ;D31E ; the next 8 bits 1.66 + ;D31F 1.67 + (Integer/parseInt "00100000" 2) ; data section 1.68 + 1.69 + 0xFA ;D320 ; load (D31F) into A 1.70 + 0x1F ;D321 --> 1.71 + 0xD3 ;D322 --> D31F 1.72 1.73 - 0xEA ;D323 ; load (A), which is 1.74 - 0x00 ;D324 --> ; 00010000, into FF00 1.75 - 0xFF ;D325 --> FF00 1.76 - 1.77 - 0x18 ;D326 ; this is the place where 1.78 - 0x01 ;D327 ; we will store whether 1.79 - 0x00 ;D328 ; "down" is pressed. 1.80 + 0xEA ;D323 ; load (A), which is 1.81 + 0x00 ;D324 --> ; 00010000, into FF00 1.82 + 0xFF ;D325 --> FF00 1.83 + 1.84 + 0x18 ;D326 ; this is the place where 1.85 + 0x01 ;D327 ; we will store whether 1.86 + 0x00 ;D328 ; "down" is pressed. 1.87 1.88 - 0xFA ;D329 ; (FF00) -> A 1.89 - 0x00 ;D32A 1.90 - 0xFF ;D32B 1.91 + 0xFA ;D329 ; (FF00) -> A 1.92 + 0x00 ;D32A 1.93 + 0xFF ;D32B 1.94 1.95 - 0xCB ;D32C ; Test whether "down" 1.96 - 0x5F ;D32D ; is pressed. 1.97 + 0xCB ;D32C ; Test whether "down" 1.98 + 0x5F ;D32D ; is pressed. 1.99 1.100 - 0x28 ;D32E ; if down is pressed, 1.101 - 0x03 ;D32F ; skip the next section 1.102 - ; of code. 1.103 - ;; down-is-not-pressed 1.104 - 0xC3 ;D330 1.105 - 0x1D ;D331 ; return to beginning 1.106 - 0xD3 ;D332 1.107 - 1.108 - ;; down-is-pressed 1.109 - 0xEA ;D334 ; write A to D328 if 1.110 - 0x28 ;D335 ; "down" was pressed 1.111 - 0xD3 ;D336 1.112 + 0x28 ;D32E ; if down is pressed, 1.113 + 0x03 ;D32F ; skip the next section 1.114 + ; of code. 1.115 + ;; down-is-not-pressed 1.116 + 0xC3 ;D330 1.117 + 0x1D ;D331 ; return to beginning 1.118 + 0xD3 ;D332 1.119 + 1.120 + ;; down-is-pressed 1.121 + 0xEA ;D334 ; write A to D328 if 1.122 + 0x28 ;D335 ; "down" was pressed 1.123 + 0xD3 ;D336 1.124 1.125 - 0xC3 ;D330 1.126 - 0x1D ;D331 ; return to beginning 1.127 - 0xD3 ;D332 1.128 - ] 1.129 - 1.130 - [])))) 1.131 + 0xC3 ;D330 1.132 + 0x1D ;D331 ; return to beginning 1.133 + 0xD3 ;D332 1.134 + ]))) 1.135 1.136 - 1.137 - 1.138 +(defn test-read-down [] 1.139 + (= (view-memory (step (step (read-down-button) [:d])) 0xD328) 1.140 + (view-memory (step (step (read-down-button))) 0xD328))) 1.141 1.142 (defn count-frames [] 1.143 (-> (tick (mid-game)) 1.144 @@ -206,7 +232,6 @@ 1.145 0xC3 ;D349 ; return to beginning 1.146 0x1D ;D34A 1.147 0xD3 ;D34B 1.148 - 1.149 ]))) 1.150 1.151 (defn step-count-frames [] 1.152 @@ -235,37 +260,11 @@ 1.153 (tick) 1.154 (print-inventory))) 1.155 1.156 -;;(defn test-read-down [] 1.157 -;; (= (view-memory (step (step (read-buttons) [:d])) 0xD328) 1.158 -;; (view-memory (step (step (read-buttons))) 0xD328))) 1.159 - 1.160 (defn test-count-frames [] 1.161 (= 255 (aget (memory ((apply comp (repeat 255 step)) 1.162 (count-frames))) 1.163 0xD31F))) 1.164 1.165 - 1.166 -(defn trace [state] 1.167 - (loop [program-counters [] 1.168 - opcodes []] 1.169 - (let [frame-boundary? 1.170 - (com.aurellem.gb.Gb/tick)] 1.171 - (println (count opcodes)) 1.172 - (if frame-boundary? 1.173 - [program-counters opcodes] 1.174 - (recur 1.175 - (conj program-counters 1.176 - (first (registers @current-state))) 1.177 - (conj opcodes 1.178 - (aget (memory @current-state) 1.179 - (PC @current-state)))))))) 1.180 - 1.181 -(defn good-trace [] 1.182 - (-> (mid-game) (tick) (IE! 0) 1.183 - (set-inv-mem [0x00 0x00 0X00 0x00]) 1.184 - (PC! item-list-start)(print-interrupt) 1.185 - (info) (tick) (info) (tick) (info))) 1.186 - 1.187 ;; specs for main bootstrap program 1.188 ;; starts in "mode-select" mode 1.189 ;; Each button press takes place in a single frame. 1.190 @@ -286,165 +285,156 @@ 1.191 ;; then, the actual bytes are entered and are written to the 1.192 ;; start address in sequence. 1.193 1.194 +(defn input-number-assembly [] 1.195 + [0x18 ;D31D ; jump over 1.196 + 0x02 ;D31E ; the next 2 bytes 1.197 + 0x00 ;D31F ; frame-count 1.198 + 0x00 ;D320 ; v-blank-prev 1.199 + 1.200 + 0xFA ;D321 1.201 + 0x41 ;D322 ; load (FF41) into A 1.202 + 0xFF ;D323 ; this contains mode flags 1.203 + 1.204 + ;; if we're in v-blank, the bit-1 is 0 1.205 + ;; and bit-2 is 1 Otherwise, it is not v-blank. 1.206 + 0xCB ;D324 ; test bit-1 of A 1.207 + 0x4F ;D325 1.208 1.209 + 0xC2 ;D326 ; if bit-1 is not 0 1.210 + 0x44 ;D327 ; GOTO not-v-blank 1.211 + 0xD3 ;D328 1.212 + 1.213 + 0xCB ;D329 ; test bit-0 of A 1.214 + 0x47 ;D32A 1.215 + 1.216 + 0xCA ;D32B ; if bit-0 is not 1 1.217 + 0x44 ;D32C ; GOTO not-v-blank 1.218 + 0xD3 ;D32D 1.219 + 1.220 + ;;; in v-blank mode 1.221 + 1.222 + ;; if v-blank-prev was 0, 1.223 + ;; increment frame-count 1.224 + 1.225 + 0xFA ;D32E ; load v-blank-prev to A 1.226 + 0x20 ;D32F 1.227 + 0xD3 ;D330 1.228 + 1.229 + 0xCB ;D331 1.230 + 0x47 ;D332 ; test bit-0 of A 1.231 + 1.232 + 0x20 ;D333 ; skip next section 1.233 + 0x07 ;D334 ; if v-blank-prev was not zero 1.234 + 1.235 + ;; v-blank was 0, increment frame-count 1.236 + 0xFA ;D335 ; load frame-count into A 1.237 + 0x1F ;D336 1.238 + 0xD3 ;D337 1.239 + 1.240 + 0x3C ;D338 ; inc A 1.241 + 1.242 + 0xEA ;D339 ; load A into frame-count 1.243 + 0x1F ;D33A 1.244 + 0xD3 ;D33B 1.245 + 1.246 + ;; set v-blank-prev to 1 1.247 + 0x3E ;D33C ; load 1 into A 1.248 + 0x01 ;D33D 1.249 + 1.250 + 0xEA ;D33E ; load A into v-blank-prev 1.251 + 0x20 ;D33F 1.252 + 0xD3 ;D340 1.253 + 1.254 + 0xC3 ;D341 ; GOTO input handling code 1.255 + 0x4E ;D342 1.256 + 0xD3 ;D343 1.257 + 1.258 + ;;; not in v-blank mode 1.259 + ;; set v-blank-prev to 0 1.260 + 0x3E ;D344 ; load 0 into A 1.261 + 0x00 ;D345 1.262 + 1.263 + 0xEA ;D346 ; load A into v-blank-prev 1.264 + 0x20 ;D347 1.265 + 0xD3 ;D348 1.266 + 1.267 + 0xC3 ;D349 ; return to beginning 1.268 + 0x1D ;D34A 1.269 + 0xD3 ;D34B 1.270 + 1.271 + 0x00 ;D34C ; these are here 1.272 + 0x00 ;D34D ; for glue 1.273 + 1.274 + 1.275 + ;;; calculate input number based on button presses 1.276 + 0x18 ;D34E ; skip next 3 bytes 1.277 + 0x03 ;D34F 1.278 + ;D350 1.279 + (Integer/parseInt "00100000" 2) ; select directional pad 1.280 + ;D351 1.281 + (Integer/parseInt "00010000" 2) ; select buttons 1.282 + 0x00 ;D352 ; input-number 1.283 + 1.284 + ;; select directional pad, store low bits in B 1.285 + 1.286 + 0xFA ;D353 ; load (D350) into A 1.287 + 0x50 ;D354 --> 1.288 + 0xD3 ;D355 --> D31F 1.289 + 1.290 + 0xEA ;D356 ; load (A), which is 1.291 + 0x00 ;D357 --> ; 00010000, into FF00 1.292 + 0xFF ;D358 --> FF00 1.293 + 1.294 + 0x06 ;D359 1.295 + ;D35A 1.296 + (Integer/parseInt "11110000" 2) ; "11110000" -> B 1.297 + 0xFA ;D35B ; (FF00) -> A 1.298 + 0x00 ;D35C 1.299 + 0xFF ;D35D 1.300 + 1.301 + 0xCB ;D35E ; swap nybbles on A 1.302 + 0x37 ;D35F 1.303 + 0xA0 ;D360 ; (AND A B) -> A 1.304 + 0x47 ;D361 ; A -> B 1.305 + 1.306 + ;; select buttons store bottom bits in C 1.307 + 1.308 + 0xFA ; ; load (D351) into A 1.309 + 0x51 ; --> 1.310 + 0xD3 ; --> D31F 1.311 + 1.312 + 0xEA ; ; load (A), which is 1.313 + 0x00 ; --> ; 00001000, into FF00 1.314 + 0xFF ; --> FF00 1.315 + 1.316 + 0x0E ; 1.317 + (Integer/parseInt "00001111" 2) ; "00001111" -> C 1.318 + 1.319 + 0xFA ; ; (FF00) -> A 1.320 + 0x00 ; 1.321 + 0xFF ; 1.322 + 1.323 + 0xA1 ; ; (AND A C) -> A 1.324 + 0x4F ; ; A -> C 1.325 + 1.326 + ;; combine the B and C registers into the input number 1.327 + 0x79 ; ; C -> A 1.328 + 0xB0 ; ; (OR A B) -> A 1.329 + 0x2F ; ; negate A 1.330 + 1.331 + 0xEA ; ; store A into input-number 1.332 + 0x52 ; 1.333 + 0xD3 ; 1.334 + 1.335 + 0xC3 ; ; return to beginning 1.336 + 0x1D ; 1.337 + 0xD3 ; 1.338 + ]) 1.339 1.340 (defn input-number [] 1.341 (-> (tick (mid-game)) 1.342 (IE! 0) ; disable interrupts 1.343 - (inject-item-assembly 1.344 - [0x18 ;D31D ; jump over 1.345 - 0x02 ;D31E ; the next 2 bytes 1.346 - 0x00 ;D31F ; frame-count 1.347 - 0x00 ;D320 ; v-blank-prev 1.348 - 1.349 - 0xFA ;D321 1.350 - 0x41 ;D322 ; load (FF41) into A 1.351 - 0xFF ;D323 ; this contains mode flags 1.352 - 1.353 - ;; if we're in v-blank, the bit-1 is 0 1.354 - ;; and bit-2 is 1 Otherwise, it is not v-blank. 1.355 - 0xCB ;D324 ; test bit-1 of A 1.356 - 0x4F ;D325 1.357 - 1.358 - 0xC2 ;D326 ; if bit-1 is not 0 1.359 - 0x44 ;D327 ; GOTO not-v-blank 1.360 - 0xD3 ;D328 1.361 - 1.362 - 0xCB ;D329 ; test bit-0 of A 1.363 - 0x47 ;D32A 1.364 - 1.365 - 0xCA ;D32B ; if bit-0 is not 1 1.366 - 0x44 ;D32C ; GOTO not-v-blank 1.367 - 0xD3 ;D32D 1.368 - 1.369 - ;;; in v-blank mode 1.370 - 1.371 - ;; if v-blank-prev was 0, 1.372 - ;; increment frame-count 1.373 - 1.374 - 0xFA ;D32E ; load v-blank-prev to A 1.375 - 0x20 ;D32F 1.376 - 0xD3 ;D330 1.377 - 1.378 - 0xCB ;D331 1.379 - 0x47 ;D332 ; test bit-0 of A 1.380 - 1.381 - 0x20 ;D333 ; skip next section 1.382 - 0x07 ;D334 ; if v-blank-prev was not zero 1.383 - 1.384 - ;; v-blank was 0, increment frame-count 1.385 - 0xFA ;D335 ; load frame-count into A 1.386 - 0x1F ;D336 1.387 - 0xD3 ;D337 1.388 - 1.389 - 0x3C ;D338 ; inc A 1.390 - 1.391 - 0xEA ;D339 ; load A into frame-count 1.392 - 0x1F ;D33A 1.393 - 0xD3 ;D33B 1.394 - 1.395 - ;; set v-blank-prev to 1 1.396 - 0x3E ;D33C ; load 1 into A 1.397 - 0x01 ;D33D 1.398 - 1.399 - 0xEA ;D33E ; load A into v-blank-prev 1.400 - 0x20 ;D33F 1.401 - 0xD3 ;D340 1.402 - 1.403 - 0xC3 ;D341 ; GOTO input handling code 1.404 - 0x4E ;D342 1.405 - 0xD3 ;D343 1.406 - 1.407 - ;;; not in v-blank mode 1.408 - ;; set v-blank-prev to 0 1.409 - 0x3E ;D344 ; load 0 into A 1.410 - 0x00 ;D345 1.411 - 1.412 - 0xEA ;D346 ; load A into v-blank-prev 1.413 - 0x20 ;D347 1.414 - 0xD3 ;D348 1.415 - 1.416 - 0xC3 ;D349 ; return to beginning 1.417 - 0x1D ;D34A 1.418 - 0xD3 ;D34B 1.419 - 1.420 - 0x00 ;D34C ; these are here 1.421 - 0x00 ;D34D ; for glue 1.422 - 1.423 - 1.424 - ;;; calculate input number based on button presses 1.425 - 0x18 ;D34E ; skip next 3 bytes 1.426 - 0x03 ;D34F 1.427 - ;D350 1.428 - (Integer/parseInt "00100000" 2) ; select directional pad 1.429 - ;D351 1.430 - (Integer/parseInt "00010000" 2) ; select buttons 1.431 - 0x00 ;D352 ; input-number 1.432 - 1.433 - ;; select directional pad, store low bits in B 1.434 - 1.435 - 0xFA ;D353 ; load (D350) into A 1.436 - 0x50 ;D354 --> 1.437 - 0xD3 ;D355 --> D31F 1.438 - 1.439 - 0xEA ;D356 ; load (A), which is 1.440 - 0x00 ;D357 --> ; 00010000, into FF00 1.441 - 0xFF ;D358 --> FF00 1.442 - 1.443 - 0x06 ;D359 1.444 - ;D35A 1.445 - (Integer/parseInt "11110000" 2) ; "11110000" -> B 1.446 - 0xFA ;D35B ; (FF00) -> A 1.447 - 0x00 ;D35C 1.448 - 0xFF ;D35D 1.449 - 1.450 - 0xCB ;D35E ; swap nybbles on A 1.451 - 0x37 ;D35F 1.452 - 0xA0 ;D360 ; (AND A B) -> A 1.453 - 0x47 ;D361 ; A -> B 1.454 - 1.455 - ;; select buttons store bottom bits in C 1.456 - 1.457 - 0xFA ; ; load (D351) into A 1.458 - 0x51 ; --> 1.459 - 0xD3 ; --> D31F 1.460 - 1.461 - 0xEA ; ; load (A), which is 1.462 - 0x00 ; --> ; 00001000, into FF00 1.463 - 0xFF ; --> FF00 1.464 - 1.465 - 0x0E ; 1.466 - (Integer/parseInt "00001111" 2) ; "00001111" -> C 1.467 - 1.468 - 0xFA ; ; (FF00) -> A 1.469 - 0x00 ; 1.470 - 0xFF ; 1.471 - 1.472 - 0xA1 ; ; (AND A C) -> A 1.473 - 0x4F ; ; A -> C 1.474 - 1.475 - 1.476 - ;; combine the B and C registers into the input number 1.477 - 0x79 ; ; C -> A 1.478 - 0xB0 ; ; (OR A B) -> A 1.479 - 0x2F ; ; negate A 1.480 - 1.481 - 0xEA ; ; store A into input-number 1.482 - 0x52 ; 1.483 - 0xD3 ; 1.484 - 1.485 - 0xC3 ; ; return to beginning 1.486 - 0x1D ; 1.487 - 0xD3 ; 1.488 - ]))) 1.489 - 1.490 -(defn print-listing [state begin end] 1.491 - (dorun (map 1.492 - (fn [opcode line] 1.493 - (println (format "0x%04X: 0x%02X" line opcode))) 1.494 - (subvec (vec (memory state)) begin end) 1.495 - (range begin end))) 1.496 - state) 1.497 + (inject-item-assembly (input-number-assembly)))) 1.498 1.499 (defn test-input-number 1.500 "Input freestyle buttons and observe the effects at the repl." 1.501 @@ -452,6 +442,288 @@ 1.502 (set-state! (input-number)) 1.503 (dotimes [_ 90000] (step (view-memory @current-state 0xD352)))) 1.504 1.505 +(defn write-memory-assembly [] 1.506 + [0x18 ;D31D ; jump over 1.507 + 0x02 ;D31E ; the next 2 bytes 1.508 + 0x00 ;D31F ; frame-count 1.509 + 0x00 ;D320 ; v-blank-prev 1.510 + 1.511 + 0xFA ;D321 1.512 + 0x41 ;D322 ; load (FF41) into A 1.513 + 0xFF ;D323 ; this contains mode flags 1.514 + 1.515 + ;; if we're in v-blank, the bit-1 is 0 1.516 + ;; and bit-2 is 1 Otherwise, it is not v-blank. 1.517 + 0xCB ;D324 ; test bit-1 of A 1.518 + 0x4F ;D325 1.519 1.520 + 0xC2 ;D326 ; if bit-1 is not 0 1.521 + 0x44 ;D327 ; GOTO not-v-blank 1.522 + 0xD3 ;D328 1.523 + 1.524 + 0xCB ;D329 ; test bit-0 of A 1.525 + 0x47 ;D32A 1.526 1.527 + 0xCA ;D32B ; if bit-0 is not 1 1.528 + 0x44 ;D32C ; GOTO not-v-blank 1.529 + 0xD3 ;D32D 1.530 + 1.531 + ;;; in v-blank mode 1.532 1.533 + ;; if v-blank-prev was 0, 1.534 + ;; increment frame-count 1.535 + 1.536 + 0xFA ;D32E ; load v-blank-prev to A 1.537 + 0x20 ;D32F 1.538 + 0xD3 ;D330 1.539 + 1.540 + 0xCB ;D331 1.541 + 0x47 ;D332 ; test bit-0 of A 1.542 + 1.543 + 0x20 ;D333 ; skip next section 1.544 + 0x07 ;D334 ; if v-blank-prev was not zero 1.545 + 1.546 + ;; v-blank was 0, increment frame-count 1.547 + 0xFA ;D335 ; load frame-count into A 1.548 + 0x1F ;D336 1.549 + 0xD3 ;D337 1.550 + 1.551 + 0x3C ;D338 ; inc A 1.552 + 1.553 + 0xEA ;D339 ; load A into frame-count 1.554 + 0x1F ;D33A 1.555 + 0xD3 ;D33B 1.556 + 1.557 + ;; set v-blank-prev to 1 1.558 + 0x3E ;D33C ; load 1 into A 1.559 + 0x01 ;D33D 1.560 + 1.561 + 0xEA ;D33E ; load A into v-blank-prev 1.562 + 0x20 ;D33F 1.563 + 0xD3 ;D340 1.564 + 1.565 + 0xC3 ;D341 ; GOTO input handling code 1.566 + 0x4E ;D342 1.567 + 0xD3 ;D343 1.568 + 1.569 + ;;; not in v-blank mode 1.570 + ;; set v-blank-prev to 0 1.571 + 0x3E ;D344 ; load 0 into A 1.572 + 0x00 ;D345 1.573 + 1.574 + 0xEA ;D346 ; load A into v-blank-prev 1.575 + 0x20 ;D347 1.576 + 0xD3 ;D348 1.577 + 1.578 + 0xC3 ;D349 ; return to beginning 1.579 + 0x1D ;D34A 1.580 + 0xD3 ;D34B 1.581 + 1.582 + 0x00 ;D34C ; these are here 1.583 + 0x00 ;D34D ; for glue 1.584 + 1.585 + 1.586 + ;;; calculate input number based on button presses 1.587 + 0x18 ;D34E ; skip next 3 bytes 1.588 + 0x03 ;D34F 1.589 + ;D350 1.590 + (Integer/parseInt "00100000" 2) ; select directional pad 1.591 + ;D351 1.592 + (Integer/parseInt "00010000" 2) ; select buttons 1.593 + 0x00 ;D352 ; input-number 1.594 + 1.595 + ;; select directional pad, store low bits in B 1.596 + 1.597 + 0xFA ;D353 ; load (D350) into A 1.598 + 0x50 ;D354 --> 1.599 + 0xD3 ;D355 --> D31F 1.600 + 1.601 + 0xEA ;D356 ; load (A), which is 1.602 + 0x00 ;D357 --> ; 00010000, into FF00 1.603 + 0xFF ;D358 --> FF00 1.604 + 1.605 + 0x06 ;D359 1.606 + ;D35A 1.607 + (Integer/parseInt "11110000" 2) ; "11110000" -> B 1.608 + 0xFA ;D35B ; (FF00) -> A 1.609 + 0x00 ;D35C 1.610 + 0xFF ;D35D 1.611 + 1.612 + 0xCB ;D35E ; swap nybbles on A 1.613 + 0x37 ;D35F 1.614 + 0xA0 ;D360 ; (AND A B) -> A 1.615 + 0x47 ;D361 ; A -> B 1.616 + 1.617 + ;; select buttons store bottom bits in C 1.618 + 1.619 + 0xFA ;D362 ; load (D351) into A 1.620 + 0x51 ;D363 --> 1.621 + 0xD3 ;D364 --> D31F 1.622 + 1.623 + 0xEA ;D365 ; load (A), which is 1.624 + 0x00 ;D366 --> ; 00001000, into FF00 1.625 + 0xFF ;D367 --> FF00 1.626 + 1.627 + 0x0E ;D368 1.628 + ;D369 1.629 + (Integer/parseInt "00001111" 2) ; "00001111" -> C 1.630 + 1.631 + 0xFA ;D36A ; (FF00) -> A 1.632 + 0x00 ;D36B 1.633 + 0xFF ;D36C 1.634 + 1.635 + 0xA1 ;D36D ; (AND A C) -> A 1.636 + 0x4F ;D36E ; A -> C 1.637 + 1.638 + ;; combine the B and C registers into the input number 1.639 + 0x79 ;D36F ; C -> A 1.640 + 0xB0 ;D370 ; (OR A B) -> A 1.641 + 0x2F ;D371 ; negate A 1.642 + 1.643 + 0xEA ;D372 ; store A into input-number 1.644 + 0x52 ;D373 1.645 + 0xD3 ;D374 1.646 + 1.647 + 0xC3 ;D375 ; GOTO state machine 1.648 + ;;0x1D 1.649 + 0x80 ;D376 1.650 + 0xD3 ;D377 1.651 + 1.652 + 0x00 ;D378 1.653 + 0x00 ;D379 1.654 + 0x00 ;D37A 1.655 + 0x00 ;D37B ; these are here because 1.656 + 0x00 ;D37C ; I messed up :( 1.657 + 0x00 ;D37D 1.658 + 0x00 ;D37E 1.659 + 0x00 ;D37F 1.660 + 1.661 + ;; beginning of main state machine 1.662 + 0x18 ;D380 ; Declaration of variables 1.663 + 0x05 ;D381 ; 5 variables: 1.664 + 0x00 ;D382 ; current-mode 1.665 + 0x00 ;D383 ; bytes-left-to-write 1.666 + 0x00 ;D384 ; unused 1.667 + 0x00 ;D385 ; unused 1.668 + 0x00 ;D386 ; unused 1.669 + 1.670 + 1.671 + ;; banch on current mode 1.672 + ;; mode 0 -- input-mode mode 1.673 + ;; means that we are waiting for a mode, so set the mode to 1.674 + ;; whatever is currently in input number. If nothing is 1.675 + ;; entered, then the program stays in input-mode mode 1.676 + 1.677 + 0xFA ;D387 ; load current-mode (0xD382) 1.678 + 0x82 ;D388 ; into A 1.679 + 0xD3 ;D389 1.680 + 1.681 + 0x00 ;D38A 1.682 + 1.683 + 0xFE ;D38B 1.684 + 0x00 ;D38C ; compare A with 0x00 1.685 + 1.686 + ;; TODO make this jump non-absolute 1.687 + 1.688 + 0xCA ;D38D ; GOTO Mode 0 if current-mode is 0 1.689 + 0xA8 ;D38E 1.690 + 0xD3 ;D38F 1.691 + 1.692 + 0x00 ;D390 1.693 + 0x00 ;D391 1.694 + 0x00 ;D392 1.695 + 0x00 ;D393 1.696 + 0x00 ;D394 1.697 + 0x00 ;D395 1.698 + 0x00 ;D396 1.699 + 0x00 ;D397 1.700 + 0x00 ;D398 1.701 + 0x00 ;D399 1.702 + 0x00 ;D39A 1.703 + 0x00 ;D39B 1.704 + 0x00 ;D39C 1.705 + 0x00 ;D39D 1.706 + 0x00 ;D39E 1.707 + 0x00 ;D39F 1.708 + 0x00 ;D3A0 1.709 + 0x00 ;D3A1 1.710 + 0x00 ;D3A2 1.711 + 0x00 ;D3A3 1.712 + 0x00 ;D3A4 1.713 + ;; End of Mode checking, goto beginning 1.714 + 0xC3 ;D3A5 1.715 + 0x1D ;D3A6 1.716 + 0xD3 ;D3A7 1.717 + ;; Mode 0 1.718 + ;; set current-mode to input-number 1.719 + 0xFA ;D3A8 ; load input-number (0xD352) 1.720 + 0x52 ;D3A9 ; into A 1.721 + 0xD3 ;D3AA 1.722 + 1.723 + 0xEA ;D3AB ; load A into current-mode 1.724 + 0x82 ;D3AC ; (0xD382) 1.725 + 0xD3 ;D3AD 1.726 + 1.727 + 0xC3 ;D3AE ; go back to beginning 1.728 + 0x1D ;D3AF 1.729 + 0xD3 ;D3B0 1.730 + 1.731 + 0x00 ;D3B1 1.732 + 0x00 ;D3B2 1.733 + 0x00 ;D3B3 1.734 + 0x00 ;D3B4 1.735 + 0x00 ;D3B5 1.736 + 0x00 ;D3B6 1.737 + 0x00 ;D3B7 1.738 + 0x00 ;D3B8 1.739 + 0x00 ;D3B9 1.740 + 0x00 ;D3BA 1.741 + 0x00 ;D3BB 1.742 + 0x00 ;D3BC 1.743 + 0x00 ;D3BD 1.744 + 0x00 ;D3BE 1.745 + 0x00 ;D3BF 1.746 + 0x00 ;D3C0 1.747 + 0x00 ;D3C1 1.748 + 0x00 ;D3C2 1.749 + 0x00 ;D3C3 1.750 + 0x00 ;D3C4 1.751 + 0x00 ;D3C5 1.752 + 0x00 ;D3C6 1.753 + 0x00 ;D3C7 1.754 + 0x00 ;D3C8 1.755 + 0x00 ;D3C9 1.756 + 0x00 ;D3CA 1.757 + 0x00 ;D3CB 1.758 + 0x00 ;D3CC 1.759 + 0x00 ;D3CD 1.760 + 0x00 ;D3CE 1.761 + 0x00 ;D3CF 1.762 + 0x00 ;D3D0 1.763 + 0x00 ;D3D1 1.764 + 0x00 ;D3D2 1.765 + 0x00 ;D3D3 1.766 + 0x00 ;D3D4 1.767 + 0x00 ;D3D5 1.768 + 0x00 ;D3D6 1.769 + 1.770 + 1.771 + 1.772 + 1.773 + 0xC3 ; ; Complete Loop 1.774 + 0x1D ; 1.775 + 0xD3 ; 1.776 + 1.777 + 1.778 + 1.779 + ]) 1.780 + 1.781 + 1.782 +(def frame-count 0xD31F) 1.783 +(def input 0xD352) 1.784 +(def current-mode 0xD382) 1.785 + 1.786 +(defn write-memory [] 1.787 + (-> (tick (mid-game)) 1.788 + (IE! 0) ; disable interrupts 1.789 + (inject-item-assembly (write-memory-assembly))))