Mercurial > vba-clojure
changeset 115:39fb0cbab25e
working on preliminary bootstrap code
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Fri, 16 Mar 2012 16:52:29 -0500 |
parents | a454730d92dd |
children | e45031af5327 |
files | clojure/com/aurellem/assembly.clj |
diffstat | 1 files changed, 205 insertions(+), 39 deletions(-) [+] |
line wrap: on
line diff
1.1 --- a/clojure/com/aurellem/assembly.clj Fri Mar 16 13:51:17 2012 -0500 1.2 +++ b/clojure/com/aurellem/assembly.clj Fri Mar 16 16:52:29 2012 -0500 1.3 @@ -125,32 +125,12 @@ 1.4 [])))) 1.5 1.6 1.7 -;; specs for main bootstrap program 1.8 -;; starts in "mode-select" mode 1.9 -;; Each button press takes place in a single frame. 1.10 -;; mode-select-mode takes one of the main buttons 1.11 -;; which selects one of up to eight modes 1.12 -;; mode 1 activated by the "A" button 1.13 -;; the next two button presses indicates the start 1.14 -;; memory location which to which the bootstrap 1.15 -;; program will write. 1.16 -;; This is done by using each of the eight buttons to 1.17 -;; spell out an 8 bit number. The order of buttons is 1.18 -;; ["A" "B" "start" "select" "up" "right" "down" "left"], 1.19 -;; [:a :start :l] --> 10100001 1.20 - 1.21 -;; the next button press determines how many bytes are to be 1.22 -;; written, starting at the start position. 1.23 - 1.24 -;; then, the actual bytes are entered and are written to the 1.25 -;; start address in sequence. 1.26 1.27 1.28 (defn count-frames [] 1.29 (-> (tick (mid-game)) 1.30 (IE! 0) ; disable interrupts 1.31 (inject-item-assembly 1.32 - ;; write 00010000 to 0xFF00 to select joypad 1.33 [0x18 ;D31D ; jump over 1.34 0x02 ;D31E ; the next 2 bytes 1.35 0x00 ;D31F ; frame-count 1.36 @@ -159,8 +139,6 @@ 1.37 0xFA ;D321 1.38 0x41 ;D322 ; load (FF41) into A 1.39 0xFF ;D323 ; this contains mode flags 1.40 - 1.41 - 1.42 1.43 ;; if we're in v-blank, the bit-1 is 0 1.44 ;; and bit-2 is 1 Otherwise, it is not v-blank. 1.45 @@ -168,14 +146,14 @@ 1.46 0x4F ;D325 1.47 1.48 0xC2 ;D326 ; if bit-1 is not 0 1.49 - 0x43 ;D327 ; GOTO not-v-blank 1.50 + 0x44 ;D327 ; GOTO not-v-blank 1.51 0xD3 ;D328 1.52 1.53 0xCB ;D329 ; test bit-0 of A 1.54 0x47 ;D32A 1.55 1.56 0xCA ;D32B ; if bit-0 is not 1 1.57 - 0x43 ;D32C ; GOTO not-v-blank 1.58 + 0x44 ;D32C ; GOTO not-v-blank 1.59 0xD3 ;D32D 1.60 1.61 ;;; in v-blank mode 1.62 @@ -212,22 +190,23 @@ 1.63 0x20 ;D33F 1.64 0xD3 ;D340 1.65 1.66 - 0x18 ;D341 ; skip not-in-v-blank section 1.67 - 0x05 ;D342 1.68 + 0xC3 ;D341 ; return to beginning 1.69 + 0x1D ;D342 1.70 + 0xD3 ;D343 1.71 1.72 ;;; not in v-blank mode 1.73 ;; set v-blank-prev to 0 1.74 - 0x3E ;D343 ; load 0 into A 1.75 - 0x00 ;D344 1.76 + 0x3E ;D344 ; load 0 into A 1.77 + 0x00 ;D345 1.78 1.79 - 0xEA ;D345 ; load A into v-blank-prev 1.80 - 0x20 ;D346 1.81 - 0xD3 ;D347 1.82 + 0xEA ;D346 ; load A into v-blank-prev 1.83 + 0x20 ;D347 1.84 + 0xD3 ;D348 1.85 + 1.86 + 0xC3 ;D349 ; return to beginning 1.87 + 0x1D ;D34A 1.88 + 0xD3 ;D34B 1.89 1.90 - 1.91 - 0xC3 ;D348 ; return to beginning 1.92 - 0x1D ;D349 1.93 - 0xD3 ;D34A 1.94 ]))) 1.95 1.96 (defn step-count-frames [] 1.97 @@ -256,10 +235,16 @@ 1.98 (tick) 1.99 (print-inventory))) 1.100 1.101 -(defn test-read-down [] 1.102 - (= (view-memory (step (step (read-buttons) [:d])) 0xD328) 1.103 - (view-memory (step (step (read-buttons))) 0xD328))) 1.104 - 1.105 +;;(defn test-read-down [] 1.106 +;; (= (view-memory (step (step (read-buttons) [:d])) 0xD328) 1.107 +;; (view-memory (step (step (read-buttons))) 0xD328))) 1.108 + 1.109 +(defn test-count-frames [] 1.110 + (= 255 (aget (memory ((apply comp (repeat 255 step)) 1.111 + (count-frames))) 1.112 + 0xD31F))) 1.113 + 1.114 + 1.115 (defn trace [state] 1.116 (loop [program-counters [] 1.117 opcodes []] 1.118 @@ -281,11 +266,192 @@ 1.119 (PC! item-list-start)(print-interrupt) 1.120 (info) (tick) (info) (tick) (info))) 1.121 1.122 +;; specs for main bootstrap program 1.123 +;; starts in "mode-select" mode 1.124 +;; Each button press takes place in a single frame. 1.125 +;; mode-select-mode takes one of the main buttons 1.126 +;; which selects one of up to eight modes 1.127 +;; mode 1 activated by the "A" button 1.128 +;; the next two button presses indicates the start 1.129 +;; memory location which to which the bootstrap 1.130 +;; program will write. 1.131 +;; This is done by using each of the eight buttons to 1.132 +;; spell out an 8 bit number. The order of buttons is 1.133 +;; ["A" "B" "start" "select" "up" "right" "down" "left"], 1.134 +;; [:a :start :l] --> 10100001 1.135 1.136 +;; the next button press determines how many bytes are to be 1.137 +;; written, starting at the start position. 1.138 1.139 +;; then, the actual bytes are entered and are written to the 1.140 +;; start address in sequence. 1.141 1.142 1.143 1.144 +(defn input-number [] 1.145 + (-> (tick (mid-game)) 1.146 + (IE! 0) ; disable interrupts 1.147 + (inject-item-assembly 1.148 + [0x18 ;D31D ; jump over 1.149 + 0x02 ;D31E ; the next 2 bytes 1.150 + 0x00 ;D31F ; frame-count 1.151 + 0x00 ;D320 ; v-blank-prev 1.152 + 1.153 + 0xFA ;D321 1.154 + 0x41 ;D322 ; load (FF41) into A 1.155 + 0xFF ;D323 ; this contains mode flags 1.156 + 1.157 + ;; if we're in v-blank, the bit-1 is 0 1.158 + ;; and bit-2 is 1 Otherwise, it is not v-blank. 1.159 + 0xCB ;D324 ; test bit-1 of A 1.160 + 0x4F ;D325 1.161 1.162 + 0xC2 ;D326 ; if bit-1 is not 0 1.163 + 0x44 ;D327 ; GOTO not-v-blank 1.164 + 0xD3 ;D328 1.165 + 1.166 + 0xCB ;D329 ; test bit-0 of A 1.167 + 0x47 ;D32A 1.168 1.169 + 0xCA ;D32B ; if bit-0 is not 1 1.170 + 0x44 ;D32C ; GOTO not-v-blank 1.171 + 0xD3 ;D32D 1.172 + 1.173 + ;;; in v-blank mode 1.174 1.175 + ;; if v-blank-prev was 0, 1.176 + ;; increment frame-count 1.177 + 1.178 + 0xFA ;D32E ; load v-blank-prev to A 1.179 + 0x20 ;D32F 1.180 + 0xD3 ;D330 1.181 + 1.182 + 0xCB ;D331 1.183 + 0x47 ;D332 ; test bit-0 of A 1.184 + 1.185 + 0x20 ;D333 ; skip next section 1.186 + 0x07 ;D334 ; if v-blank-prev was not zero 1.187 + 1.188 + ;; v-blank was 0, increment frame-count 1.189 + 0xFA ;D335 ; load frame-count into A 1.190 + 0x1F ;D336 1.191 + 0xD3 ;D337 1.192 + 1.193 + 0x3C ;D338 ; inc A 1.194 + 1.195 + 0xEA ;D339 ; load A into frame-count 1.196 + 0x1F ;D33A 1.197 + 0xD3 ;D33B 1.198 + 1.199 + ;; set v-blank-prev to 1 1.200 + 0x3E ;D33C ; load 1 into A 1.201 + 0x01 ;D33D 1.202 + 1.203 + 0xEA ;D33E ; load A into v-blank-prev 1.204 + 0x20 ;D33F 1.205 + 0xD3 ;D340 1.206 + 1.207 + 0xC3 ;D341 ; GOTO input handling code 1.208 + 0x4E ;D342 1.209 + 0xD3 ;D343 1.210 + 1.211 + ;;; not in v-blank mode 1.212 + ;; set v-blank-prev to 0 1.213 + 0x3E ;D344 ; load 0 into A 1.214 + 0x00 ;D345 1.215 + 1.216 + 0xEA ;D346 ; load A into v-blank-prev 1.217 + 0x20 ;D347 1.218 + 0xD3 ;D348 1.219 + 1.220 + 0xC3 ;D349 ; return to beginning 1.221 + 0x1D ;D34A 1.222 + 0xD3 ;D34B 1.223 + 1.224 + 0x00 ;D34C ; these are here 1.225 + 0x00 ;D34D ; for glue 1.226 + 1.227 + 1.228 + ;;; calculate input number based on button presses 1.229 + 0x18 ;D34E ; skip next 3 bytes 1.230 + 0x03 ;D34F 1.231 + ;D350 1.232 + (Integer/parseInt "00100000" 2) ; select directional pad 1.233 + ;D351 1.234 + (Integer/parseInt "00010000" 2) ; select buttons 1.235 + 0x00 ;D352 ; input-number 1.236 + 1.237 + ;; select directional pad, store low bits in B 1.238 + 1.239 + 0xFA ;D353 ; load (D350) into A 1.240 + 0x50 ;D354 --> 1.241 + 0xD3 ;D355 --> D31F 1.242 + 1.243 + 0xEA ;D356 ; load (A), which is 1.244 + 0x00 ;D357 --> ; 00010000, into FF00 1.245 + 0xFF ;D358 --> FF00 1.246 + 1.247 + 0x06 ;D359 1.248 + ;D35A 1.249 + (Integer/parseInt "11110000") ; "11110000" -> B 1.250 + 0xFA ;D35B ; (FF00) -> A 1.251 + 0x00 ;D35C 1.252 + 0xFF ;D35D 1.253 + 1.254 + 0xCB ;D35E ; swap nybbles on A 1.255 + 0x37 ;D35F 1.256 + 0xA0 ;D360 ; (AND A B) -> A 1.257 + 0x47 ;D361 ; A -> B 1.258 + 1.259 + ;; select buttons store bottom bits in C 1.260 + 1.261 + 0xFA ; ; load (D351) into A 1.262 + 0x51 ; --> 1.263 + 0xD3 ; --> D31F 1.264 + 1.265 + 0xEA ; ; load (A), which is 1.266 + 0x00 ; --> ; 00001000, into FF00 1.267 + 0xFF ; --> FF00 1.268 + 1.269 + 0x0E ; 1.270 + (Integer/parseInt "00001111") ; "00001111" -> C 1.271 + 1.272 + 0xFA ; ; (FF00) -> A 1.273 + 0x00 ; 1.274 + 0xFF ; 1.275 + 1.276 + 0xA1 ; ; (AND A C) -> A 1.277 + 0x4F ; ; A -> C 1.278 + 1.279 + 1.280 + ;; combine the B and C registers into the input number 1.281 + 0x79 ; ; C -> A 1.282 + 0xB0 ; ; (OR A B) -> A 1.283 + 0x2F ; ; negate A 1.284 + 1.285 + 0xEA ; ; store A into input-number 1.286 + 0x52 ; 1.287 + 0xD3 ; 1.288 + 1.289 + 0xC3 ; ; return to beginning 1.290 + 0x1D ; 1.291 + 0xD3 ; 1.292 + ]))) 1.293 + 1.294 + 1.295 + 1.296 + 1.297 +(defn print-listing [state begin end] 1.298 + (dorun (map 1.299 + (fn [opcode line] 1.300 + (println (format "0x%04X: 0x%02X" line opcode))) 1.301 + (subvec (vec (memory state)) begin end) 1.302 + (range begin end)))) 1.303 + 1.304 + 1.305 + 1.306 + 1.307 + 1.308 + 1.309 + 1.310 +