Mercurial > vba-clojure
diff clojure/com/aurellem/gb/dylan_assembly.clj @ 239:19fd38fe376e
revived a functional version of Dylan's assembly.
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sun, 25 Mar 2012 00:38:45 -0500 |
parents | |
children | 7c89fe478de4 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/clojure/com/aurellem/gb/dylan_assembly.clj Sun Mar 25 00:38:45 2012 -0500 1.3 @@ -0,0 +1,199 @@ 1.4 +(ns com.aurellem.gb.dylan-assembly 1.5 + "A much more compact version of write-memory-assembly" 1.6 + {:author "Dylan Holmes"} 1.7 + (:use (com.aurellem.gb gb-driver assembly util)) 1.8 + (:import [com.aurellem.gb.gb_driver SaveState])) 1.9 + 1.10 +(defn write-memory-assembly-compact 1.11 + "Currently, grabs input from the user each frame." 1.12 + [] 1.13 + [ 1.14 + ;; --------- FRAME METRONOME 1.15 + 0x18 ;; jump ahead to cleanup. first time only. 1.16 + 0x40 ;; v-blank-prev [D31E] 1.17 + 1.18 + 0xFA ;; load modes into A [D31F] 1.19 + 0x41 1.20 + 0xFF 1.21 + 1.22 + 0x47 ;; A -> B 1.23 + 0xCB ;; rotate A 1.24 + 0x2F 1.25 + 0x2F ;; invert A 1.26 + 1.27 + 0xA0 1.28 + 0x47 ;; now B_0 contains (VB==1) 1.29 + 1.30 + 0xFA ;; load v-blank-prev 1.31 + 0x1E 1.32 + 0xD3 1.33 + 1.34 + 0x2F ;; complement v-blank-prev 1.35 + 1.36 + 0xA0 ;; A & B --> A 1.37 + 0x4F ;; now C_0 contains increment? 1.38 + 1.39 + 1.40 + 0x78 ;; B->A 1.41 + 0xEA ;; spit A --> vbprev 1.42 + 0x1E 1.43 + 0xD3 1.44 + 1.45 + 0xCB ;test C_0 1.46 + 0x41 1.47 + 0x20 ; JUMP ahead to button input if nonzero 1.48 + 0x02 1.49 + 0x18 ; JUMP back to frame metronome (D31F) 1.50 + 0xE7 1.51 + 1.52 + ;; -------- GET BUTTON INPUT 1.53 + 1.54 + ;; btw, C_0 is now 1 1.55 + ;; prepare to select bits 1.56 + 1.57 + 0x06 ;; load 0x00 into B 1.58 + 0x00 ;; to initialize for "OR" loop 1.59 + 1.60 + 0x3E ;; load 0x20 into A, to measure dpad 1.61 + 0x20 1.62 + 1.63 + 1.64 + 0xE0 ;; load A into [FF00] ;; start of OR loop [D33C] 1.65 + 0x00 1.66 + 1.67 + 0xF0 ;; load A from [FF00] 1.68 + 0x00 1.69 + 1.70 + 0xE6 ;; bitmask 00001111 1.71 + 0x0F 1.72 + 1.73 + 0xB0 ;; A or B --> A 1.74 + 0xCB 1.75 + 0x41 ;; test bit 0 of C 1.76 + 0x28 ;; JUMP forward if 0 1.77 + 0x08 1.78 + 1.79 + 0x47 ;; A -> B 1.80 + 0xCB ;; swap B nybbles 1.81 + 0x30 1.82 + 0x0C ;; increment C 1.83 + 0x3E ;; load 0x10 into A, to measure btns 1.84 + 0x10 1.85 + 0x18 ;; JUMP back to "load A into [FF00]" [20 steps?] 1.86 + 0xED 1.87 + 1.88 + 1.89 + ;; ------ TAKE ACTION BASED ON USER INPUT 1.90 + 1.91 + ;; "input mode" 1.92 + ;; mode 0x00 : select mode 1.93 + ;; mode 0x08 : select bytes-to-write 1.94 + ;; mode 0x10 : select hi-bit 1.95 + ;; mode 0x18 : select lo-bit 1.96 + 1.97 + ;; "output mode" 1.98 + ;; mode 0x20 : write bytes 1.99 + ;; mode 0xFF : jump PC 1.100 + 1.101 + 1.102 + ;; registers 1.103 + ;; D : mode select 1.104 + ;; E : count of bytes to write 1.105 + ;; H : address-high 1.106 + ;; L : address-low 1.107 + 1.108 + ;; now A contains the pressed keys 1.109 + 0x2F ; complement A, by request. [D34F] 1.110 + 1.111 + 0x47 ; A->B ;; now B contains the pressed keys 1.112 + 0x7B ; E->A ;; now A contains the count. 1.113 + 1.114 + 0xCB ; test bit 5 of D (are we in o/p mode?) 1.115 + 0x6A 1.116 + 0x28 ; if test == 0, skip this o/p section 1.117 + 0x13 ; JUMP 1.118 + 1.119 + 0xCB ; else, test bit 0 of D (fragile; are we in pc mode?) 1.120 + 0x42 1.121 + 0x28 ; if test == 0, skip the following command 1.122 + 0x01 1.123 + 1.124 + ;; output mode I: moving the program counter 1.125 + 0xE9 ; ** move PC to (HL) 1.126 + 1.127 + ;; output mode II: writing bytes 1.128 + 0xFE ; A compare 0. finished writing? 1.129 + 0x00 1.130 + 0x20 ; if we are not finished, skip cleanup 1.131 + 0x04 ; JUMP 1.132 + 1.133 + ;; CLEANUP 1.134 + ;; btw, A is already zero. 1.135 + 0xAF ; zero A [D35F] 1.136 + 0x57 ; A->D; makes D=0. 1.137 + 0x18 ; end of frame 1.138 + 0xBC 1.139 + 1.140 + ;; ---- end of cleanup 1.141 + 1.142 + 1.143 + ;; continue writing bytes 1.144 + 0x1D ;; decrement E, the number of bytes to write [D363] 1.145 + 0x78 ;; B->A; now A contains the pressed keys 1.146 + 0x77 ;; copy A to (HL) 1.147 + 0x23 ;; increment HL 1.148 + 0x18 ;; end frame. [goto D31F] 1.149 + 0xB6 ;; TODO: set skip length backwards 1.150 + 1.151 + 1.152 + ;; ---- end of o/p section 1.153 + 1.154 + ;; i/p mode 1.155 + ;; adhere to the mode discipline: 1.156 + ;; D must be one of 0x00 0x08 0x10 0x18. 1.157 + 1.158 + 0x3E ;; load the constant 57 into A. [D369] 1.159 + 0x57 1.160 + 0x82 ;; add the mode to A 1.161 + 0xEA ;; store A into "thing to execute" 1.162 + 0x74 1.163 + 0xD3 1.164 + 1.165 + 0x3E ;; load the constant 8 into A 1.166 + 0x08 1.167 + 0x82 ;; add the mode to A 1.168 + 1.169 + 0x57 ;; store the incremented mode into D 1.170 + 0x78 ;; B->A; now A contains the pressed keys 1.171 + 1.172 + 0x00 ;; var: thing to execute [D374] 1.173 + 1.174 + 0x18 ;; end frame 1.175 + 0xA8]) 1.176 + 1.177 +(defn write-mem-compact [] 1.178 + (-> (tick (mid-game)) 1.179 + (IE! 0) 1.180 + (inject-item-assembly (write-memory-assembly-compact)))) 1.181 + 1.182 +(defn drive-compact [] 1.183 + (-> (write-mem-compact) 1.184 + (#(do (println "memory from 0xC00F to 0xC01F:" 1.185 + (subvec (vec (memory %)) 0xC00F 0xC01F)) %)) 1.186 + (step []) 1.187 + (step []) 1.188 + (step []) 1.189 + (step [:start]) 1.190 + (step [:select]) 1.191 + (step [:u :d]) 1.192 + (step [:a :b :start :select]) 1.193 + (step [:a]) 1.194 + (step [:b]) 1.195 + (step [:a :b]) 1.196 + (step [:select]) 1.197 + (step []) 1.198 + (step []) 1.199 + (step []) 1.200 + (#(do (println "memory from 0xC00F to 0xC01F:" 1.201 + (subvec (vec (memory %)) 0xC00F 0xC01F)) %)))) 1.202 +