--- a/content/blog/2016/12/chip8-cpu.markdown Sat Dec 17 23:00:51 2016 -0500
+++ b/content/blog/2016/12/chip8-cpu.markdown Sun Dec 18 12:55:25 2016 -0500
@@ -931,41 +931,48 @@
</pre>
We'll split this into two parts to make it easier to read. First we'll make
-a `bcd` function to actually get the digits:
+a `digit` function to retrieve a digit of a number:
```lisp
-(defun-inline bcd (integer)
- (values (-<> integer (floor <> 100) (mod <> 10))
- (-<> integer (floor <> 10) (mod <> 10))
- (-<> integer (floor <> 1) (mod <> 10))))
-
+(defun-inline digit (position integer &optional (base 10))
+ (-<> integer
+ (floor <> (expt base position))
+ (mod <> base)))
```
-And make sure it works on its own:
+We could have hard-coded the base 10, but part of the Common Lisp tradition is
+making flexible functions that can be reused in the future when it's not much
+harder to do so.
+
+Let's make sure it works on its own:
+
+```lisp
+(digit 0 135)
+1
-```
-[SBCL] CHIP8> (bcd 135)
+(digit 1 135)
+3
+
+(digit 2 135)
+5
-1
-3
-5
+(digit 0 #xD6 16)
+6
+
+(digit 1 #xD6 16)
+13 ; 13 in base 10 == D in base 16
```
And then we can define the actual operation:
```lisp
(define-instruction op-ld-bcd<vx (_ r _ _) ;; LD B, Vx
- (setf (values (aref memory (+ index 0)) ; hundreds
- (aref memory (+ index 1)) ; tens
- (aref memory (+ index 2))) ; ones
- (bcd (register r))))
+ (let ((number (register r)))
+ (setf (aref memory (+ index 0)) (digit 2 number)
+ (aref memory (+ index 1)) (digit 1 number)
+ (aref memory (+ index 2)) (digit 0 number))))
```
-This takes advantage of the fact that you can use `(setf (values ...) ...)` to
-assign all the multiple values returned by `bcd` at once, without binding them
-to local variables (though because `bcd` itself is inline, there won't actually
-be any *returning* at all...).
-
[BCD]: https://en.wikipedia.org/wiki/Binary-coded_decimal
### Arithmetic
@@ -1006,7 +1013,9 @@
(-_8 (register rx) (register ry))))
```
-Again we use `(setf (values ...))` to avoid having to name intermediate results.
+This takes advantage of the fact that you can use `(setf (values ...) ...)` to
+assign the multiple values returned by a function, without binding them to local
+variables.
Notice how we just assign to `flag`. Under the hood that `flag` has been bound
with our `with-chip` macro to mean `(chip-flag chip)`, which we defined way back