|
69 | 69 | "retrieves the b parameter from the word"
|
70 | 70 | (mask-and-shift 0xFC00 10))
|
71 | 71 |
|
| 72 | +(defn- between |
| 73 | + "Determine if n is x <= n <= y" |
| 74 | + [n x y] |
| 75 | + (and (<= x n) (>= y n))) |
| 76 | + |
72 | 77 | (defn process
|
73 | 78 | [word])
|
74 | 79 |
|
75 |
| -(defn op-size [pc]) |
| 80 | +(defn op-size |
| 81 | + "Given a word, calculate how many words the |
| 82 | + next instruction will consume and return the jump distance" |
| 83 | + [pc] |
| 84 | + (let [params [(get-a pc) (get-b pc)]] |
| 85 | + (apply + 1 (map #(if (or (between % 0x10 0x17) |
| 86 | + (between % 0x1e 0x1f)) 1 0) params)))) |
76 | 87 |
|
77 | 88 | (defmulti execute get-o)
|
78 | 89 | (defmethod execute 0x0 [word]
|
|
153 | 164 | pc (get-memory :pc)]
|
154 | 165 | (if (= a b)
|
155 | 166 | (inc-memory :pc)
|
156 |
| - (change-memory :pc (+ pc 1 (op-size (inc pc))))))) |
| 167 | + (change-memory :pc (+ pc 1 (op-size (follow-memory (inc pc)))))))) |
157 | 168 | (defmethod execute 0xd [word]
|
158 | 169 | ;; IFN execute next instruction iff a!=b
|
159 | 170 | (let [[a b out] (process word)
|
160 | 171 | pc (get-memory :pc)]
|
161 | 172 | (if (not= a b)
|
162 | 173 | (inc-memory :pc)
|
163 |
| - (change-memory :pc (+ pc 1 (op-size (inc pc))))))) |
| 174 | + (change-memory :pc (+ pc 1 (op-size (follow-memory (inc pc)))))))) |
164 | 175 | (defmethod execute 0xe [word]
|
165 | 176 | ;; IFG execute next instruction iff a>b
|
166 | 177 | (let [[a b out] (process word)
|
167 | 178 | pc (get-memory :pc)]
|
168 | 179 | (if (> a b)
|
169 | 180 | (inc-memory :pc)
|
170 |
| - (change-memory :pc (+ pc 1 (op-size (inc pc))))))) |
| 181 | + (change-memory :pc (+ pc 1 (op-size (follow-memory (inc pc)))))))) |
171 | 182 | (defmethod execute 0xf [word]
|
172 | 183 | ;; IFB execute next instruction iff (a&b)!= 0
|
173 | 184 | (let [[a b out] (process word)
|
174 | 185 | pc (get-memory :pc)]
|
175 | 186 | (if (not= 0 (bit-and a b))
|
176 | 187 | (inc-memory :pc)
|
177 |
| - (change-memory :pc (+ pc 1 (op-size (inc pc))))))) |
| 188 | + (change-memory :pc (+ pc 1 (op-size (follow-memory (inc pc)))))))) |
178 | 189 |
|
179 | 190 | (defn run!
|
180 | 191 | "Start execution at 0x0000 unless specified"
|
181 | 192 | ([pc]
|
182 |
| - (set-memory pc) |
| 193 | + (change-memory :pc pc) |
183 | 194 | (run!))
|
184 | 195 | ([]
|
185 | 196 | (while true
|
|
0 commit comments