annotate 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
rev   line source
rlm@239 1 (ns com.aurellem.gb.dylan-assembly
rlm@239 2 "A much more compact version of write-memory-assembly"
rlm@239 3 {:author "Dylan Holmes"}
rlm@239 4 (:use (com.aurellem.gb gb-driver assembly util))
rlm@239 5 (:import [com.aurellem.gb.gb_driver SaveState]))
rlm@239 6
rlm@239 7 (defn write-memory-assembly-compact
rlm@239 8 "Currently, grabs input from the user each frame."
rlm@239 9 []
rlm@239 10 [
rlm@239 11 ;; --------- FRAME METRONOME
rlm@239 12 0x18 ;; jump ahead to cleanup. first time only.
rlm@239 13 0x40 ;; v-blank-prev [D31E]
rlm@239 14
rlm@239 15 0xFA ;; load modes into A [D31F]
rlm@239 16 0x41
rlm@239 17 0xFF
rlm@239 18
rlm@239 19 0x47 ;; A -> B
rlm@239 20 0xCB ;; rotate A
rlm@239 21 0x2F
rlm@239 22 0x2F ;; invert A
rlm@239 23
rlm@239 24 0xA0
rlm@239 25 0x47 ;; now B_0 contains (VB==1)
rlm@239 26
rlm@239 27 0xFA ;; load v-blank-prev
rlm@239 28 0x1E
rlm@239 29 0xD3
rlm@239 30
rlm@239 31 0x2F ;; complement v-blank-prev
rlm@239 32
rlm@239 33 0xA0 ;; A & B --> A
rlm@239 34 0x4F ;; now C_0 contains increment?
rlm@239 35
rlm@239 36
rlm@239 37 0x78 ;; B->A
rlm@239 38 0xEA ;; spit A --> vbprev
rlm@239 39 0x1E
rlm@239 40 0xD3
rlm@239 41
rlm@239 42 0xCB ;test C_0
rlm@239 43 0x41
rlm@239 44 0x20 ; JUMP ahead to button input if nonzero
rlm@239 45 0x02
rlm@239 46 0x18 ; JUMP back to frame metronome (D31F)
rlm@239 47 0xE7
rlm@239 48
rlm@239 49 ;; -------- GET BUTTON INPUT
rlm@239 50
rlm@239 51 ;; btw, C_0 is now 1
rlm@239 52 ;; prepare to select bits
rlm@239 53
rlm@239 54 0x06 ;; load 0x00 into B
rlm@239 55 0x00 ;; to initialize for "OR" loop
rlm@239 56
rlm@239 57 0x3E ;; load 0x20 into A, to measure dpad
rlm@239 58 0x20
rlm@239 59
rlm@239 60
rlm@239 61 0xE0 ;; load A into [FF00] ;; start of OR loop [D33C]
rlm@239 62 0x00
rlm@239 63
rlm@239 64 0xF0 ;; load A from [FF00]
rlm@239 65 0x00
rlm@239 66
rlm@239 67 0xE6 ;; bitmask 00001111
rlm@239 68 0x0F
rlm@239 69
rlm@239 70 0xB0 ;; A or B --> A
rlm@239 71 0xCB
rlm@239 72 0x41 ;; test bit 0 of C
rlm@239 73 0x28 ;; JUMP forward if 0
rlm@239 74 0x08
rlm@239 75
rlm@239 76 0x47 ;; A -> B
rlm@239 77 0xCB ;; swap B nybbles
rlm@239 78 0x30
rlm@239 79 0x0C ;; increment C
rlm@239 80 0x3E ;; load 0x10 into A, to measure btns
rlm@239 81 0x10
rlm@239 82 0x18 ;; JUMP back to "load A into [FF00]" [20 steps?]
rlm@239 83 0xED
rlm@239 84
rlm@239 85
rlm@239 86 ;; ------ TAKE ACTION BASED ON USER INPUT
rlm@239 87
rlm@239 88 ;; "input mode"
rlm@239 89 ;; mode 0x00 : select mode
rlm@239 90 ;; mode 0x08 : select bytes-to-write
rlm@239 91 ;; mode 0x10 : select hi-bit
rlm@239 92 ;; mode 0x18 : select lo-bit
rlm@239 93
rlm@239 94 ;; "output mode"
rlm@239 95 ;; mode 0x20 : write bytes
rlm@239 96 ;; mode 0xFF : jump PC
rlm@239 97
rlm@239 98
rlm@239 99 ;; registers
rlm@239 100 ;; D : mode select
rlm@239 101 ;; E : count of bytes to write
rlm@239 102 ;; H : address-high
rlm@239 103 ;; L : address-low
rlm@239 104
rlm@239 105 ;; now A contains the pressed keys
rlm@239 106 0x2F ; complement A, by request. [D34F]
rlm@239 107
rlm@239 108 0x47 ; A->B ;; now B contains the pressed keys
rlm@239 109 0x7B ; E->A ;; now A contains the count.
rlm@239 110
rlm@239 111 0xCB ; test bit 5 of D (are we in o/p mode?)
rlm@239 112 0x6A
rlm@239 113 0x28 ; if test == 0, skip this o/p section
rlm@239 114 0x13 ; JUMP
rlm@239 115
rlm@239 116 0xCB ; else, test bit 0 of D (fragile; are we in pc mode?)
rlm@239 117 0x42
rlm@239 118 0x28 ; if test == 0, skip the following command
rlm@239 119 0x01
rlm@239 120
rlm@239 121 ;; output mode I: moving the program counter
rlm@239 122 0xE9 ; ** move PC to (HL)
rlm@239 123
rlm@239 124 ;; output mode II: writing bytes
rlm@239 125 0xFE ; A compare 0. finished writing?
rlm@239 126 0x00
rlm@239 127 0x20 ; if we are not finished, skip cleanup
rlm@239 128 0x04 ; JUMP
rlm@239 129
rlm@239 130 ;; CLEANUP
rlm@239 131 ;; btw, A is already zero.
rlm@239 132 0xAF ; zero A [D35F]
rlm@239 133 0x57 ; A->D; makes D=0.
rlm@239 134 0x18 ; end of frame
rlm@239 135 0xBC
rlm@239 136
rlm@239 137 ;; ---- end of cleanup
rlm@239 138
rlm@239 139
rlm@239 140 ;; continue writing bytes
rlm@239 141 0x1D ;; decrement E, the number of bytes to write [D363]
rlm@239 142 0x78 ;; B->A; now A contains the pressed keys
rlm@239 143 0x77 ;; copy A to (HL)
rlm@239 144 0x23 ;; increment HL
rlm@239 145 0x18 ;; end frame. [goto D31F]
rlm@239 146 0xB6 ;; TODO: set skip length backwards
rlm@239 147
rlm@239 148
rlm@239 149 ;; ---- end of o/p section
rlm@239 150
rlm@239 151 ;; i/p mode
rlm@239 152 ;; adhere to the mode discipline:
rlm@239 153 ;; D must be one of 0x00 0x08 0x10 0x18.
rlm@239 154
rlm@239 155 0x3E ;; load the constant 57 into A. [D369]
rlm@239 156 0x57
rlm@239 157 0x82 ;; add the mode to A
rlm@239 158 0xEA ;; store A into "thing to execute"
rlm@239 159 0x74
rlm@239 160 0xD3
rlm@239 161
rlm@239 162 0x3E ;; load the constant 8 into A
rlm@239 163 0x08
rlm@239 164 0x82 ;; add the mode to A
rlm@239 165
rlm@239 166 0x57 ;; store the incremented mode into D
rlm@239 167 0x78 ;; B->A; now A contains the pressed keys
rlm@239 168
rlm@239 169 0x00 ;; var: thing to execute [D374]
rlm@239 170
rlm@239 171 0x18 ;; end frame
rlm@239 172 0xA8])
rlm@239 173
rlm@239 174 (defn write-mem-compact []
rlm@239 175 (-> (tick (mid-game))
rlm@239 176 (IE! 0)
rlm@239 177 (inject-item-assembly (write-memory-assembly-compact))))
rlm@239 178
rlm@239 179 (defn drive-compact []
rlm@239 180 (-> (write-mem-compact)
rlm@239 181 (#(do (println "memory from 0xC00F to 0xC01F:"
rlm@239 182 (subvec (vec (memory %)) 0xC00F 0xC01F)) %))
rlm@239 183 (step [])
rlm@239 184 (step [])
rlm@239 185 (step [])
rlm@239 186 (step [:start])
rlm@239 187 (step [:select])
rlm@239 188 (step [:u :d])
rlm@239 189 (step [:a :b :start :select])
rlm@239 190 (step [:a])
rlm@239 191 (step [:b])
rlm@239 192 (step [:a :b])
rlm@239 193 (step [:select])
rlm@239 194 (step [])
rlm@239 195 (step [])
rlm@239 196 (step [])
rlm@239 197 (#(do (println "memory from 0xC00F to 0xC01F:"
rlm@239 198 (subvec (vec (memory %)) 0xC00F 0xC01F)) %))))
rlm@239 199