emacs.d/clones/lisp/stevelosh.com/blog/2016/12/chip8-cpu/index.html

1190 lines
97 KiB
HTML
Raw Normal View History

2022-10-07 15:47:14 +02:00
<!DOCTYPE html>
<html lang='en'><head><meta charset='utf-8' /><meta name='pinterest' content='nopin' /><link href='http://stevelosh.com/static/css/style.css' rel='stylesheet' type='text/css' /><link href='http://stevelosh.com/static/css/print.css' rel='stylesheet' type='text/css' media='print' /><title>CHIP-8 in Common Lisp: The CPU / Steve Losh</title></head><body><header><a id='logo' href='http://stevelosh.com/'>Steve Losh</a><nav><a href='http://stevelosh.com/blog/'>Blog</a> - <a href='http://stevelosh.com/projects/'>Projects</a> - <a href='http://stevelosh.com/photography/'>Photography</a> - <a href='http://stevelosh.com/links/'>Links</a> - <a href='http://stevelosh.com/rss.xml'>Feed</a></nav></header><hr class='main-separator' /><main id='page-blog-entry'><article><h1><a href='index.html'>CHIP-8 in Common Lisp: The CPU</a></h1><p class='date'>Posted on December 19th, 2016.</p><p>A while back I decided to try to write a Game Boy emulator in Common Lisp based
on <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript">this series of articles</a>. I made some good progress but eventually
got bogged down because I was trying to learn a bunch of complex new things at
once:</p>
<ul>
<li>How to write an emulator</li>
<li>How to use Qt with Common Lisp</li>
<li>How the Game Boy works internally</li>
</ul>
<p>Instead of dragging on, I decided to take a break and try something simpler:
a <a href="https://en.wikipedia.org/wiki/CHIP-8">CHIP-8</a> emulator/interpreter. The CHIP-8 is much simpler than the Game
Boy, which made it easier to experiment with the rest of the infrastructure.</p>
<p>In this post and a couple of future ones I'll walk through all of my CHIP-8
emulator implementation. To give you a rough idea of the size of the project,
<code>cloc</code> reports:</p>
<ul>
<li>Basic emulator: 415 lines</li>
<li>Debugging/disassembling infrastructure: 142 lines</li>
<li>Screen GUI: 153 lines</li>
<li>Graphical debugger: 295 lines</li>
</ul>
<p>This first post will deal with emulating the CHIP-8's CPU.</p>
<p>The full series of posts so far:</p>
<ol>
<li><a href="index.html">CHIP-8 in Common Lisp: The CPU</a></li>
<li><a href="../chip8-graphics/index.html">CHIP-8 in Common Lisp: Graphics</a></li>
<li><a href="../chip8-input/index.html">CHIP-8 in Common Lisp: Input</a></li>
<li><a href="../chip8-sound/index.html">CHIP-8 in Common Lisp: Sound</a></li>
<li><a href="../../../2017/01/chip8-disassembly/index.html">CHIP-8 in Common Lisp: Disassembly</a></li>
<li><a href="../../../2017/01/chip8-debugging-infrastructure/index.html">CHIP-8 in Common Lisp: Debugging Infrastructure</a></li>
<li><a href="../../../2017/01/chip8-menus/index.html">CHIP-8 in Common Lisp: Menus</a></li>
</ol>
<p>The full emulator source is on <a href="https://bitbucket.org/sjl/cl-chip8">BitBucket</a> and <a href="https://github.com/sjl/cl-chip8">GitHub</a>.</p>
<ol class="table-of-contents"><li><a href="index.html#s1-libraries">Libraries</a></li><li><a href="index.html#s2-chip-8-references">CHIP-8 References</a></li><li><a href="index.html#s3-the-main-data-structure">The Main Data Structure</a><ol><li><a href="index.html#s4-registers">Registers</a></li><li><a href="index.html#s5-the-stack">The Stack</a></li><li><a href="index.html#s6-memory">Memory</a></li><li><a href="index.html#s7-currently-loaded-rom">Currently-Loaded ROM</a></li><li><a href="index.html#s8-the-flag-register">The Flag Register</a></li></ol></li><li><a href="index.html#s9-removing-tedium">Removing Tedium</a></li><li><a href="index.html#s10-infrastructure">Infrastructure</a><ol><li><a href="index.html#s11-resetting">Resetting</a></li><li><a href="index.html#s12-loading-roms">Loading ROMs</a></li><li><a href="index.html#s13-the-main-loop-s">The Main Loop(s)</a></li><li><a href="index.html#s14-individual-cycles">Individual Cycles</a></li><li><a href="index.html#s15-instruction-dispatch">Instruction Dispatch</a></li></ol></li><li><a href="index.html#s16-instructions">Instructions</a><ol><li><a href="index.html#s17-random-numbers">Random Numbers</a></li><li><a href="index.html#s18-define-instruction">Define-Instruction</a></li><li><a href="index.html#s19-jumps-and-calls">Jumps and Calls</a></li><li><a href="index.html#s20-binary-coded-decimal">Binary-Coded Decimal</a></li><li><a href="index.html#s21-arithmetic">Arithmetic</a></li><li><a href="index.html#s22-shifting">Shifting</a></li><li><a href="index.html#s23-logical-operations">Logical Operations</a></li><li><a href="index.html#s24-macro-map">Macro-Map</a></li><li><a href="index.html#s25-branching">Branching</a></li><li><a href="index.html#s26-loads">Loads</a></li></ol></li><li><a href="index.html#s27-future">Future</a></li></ol>
<h2 id="s1-libraries"><a href="index.html#s1-libraries">Libraries</a></h2>
<p>The emulator uses a few Common Lisp libraries to make things easier:</p>
<ul>
<li><a href="https://common-lisp.net/project/bordeaux-threads/">bordeaux-threads</a> to handle threading.</li>
<li><a href="https://github.com/nightfly19/cl-arrows">cl-arrows</a> for an implementation of Clojure's <code>-&lt;&gt;</code> threading macro.</li>
<li><a href="https://github.com/sjl/cl-losh">cl-losh</a> is my own personal utility library.</li>
<li><a href="https://filonenko-mikhail.github.io/cl-portaudio/">cl-portaudio</a> for audio.</li>
<li><a href="https://common-lisp.net/project/iterate/">iterate</a> for a much nicer version of <code>loop</code> called <code>iterate</code>. My utility
library contains several <code>iterate</code> drivers (some of which I've written about
before).</li>
<li><a href="https://shinmera.github.io/qtools/">qtools</a> to handle creating a GUI with Qt.</li>
<li><a href="https://github.com/tarballs-are-good/quickutil">quickutil</a> for some miscellaneous utility functions from Alexandria and
elsewhere.</li>
</ul>
<p>I'll try to remember to mention whenever I use a function that's not built-in to
Common Lisp, but I might forget, in which case it's probably in one of these.</p>
<h2 id="s2-chip-8-references"><a href="index.html#s2-chip-8-references">CHIP-8 References</a></h2>
<p>There's a good amount of information available about the CHIP-8 online. The
references I used most often were:</p>
<ul>
<li><a href="http://devernay.free.fr/hacks/chip8/C8TECH10.HTM">Cowgod's &quot;CHIP-8 Technical Reference&quot;</a></li>
<li><a href="http://www.multigesture.net/articles/how-to-write-an-emulator-CHIP-8-interpreter/">Laurence Muller's &quot;How to write an emulator (CHIP-8 interpreter)&quot;</a></li>
<li><a href="http://mattmik.com/files/chip8/mastering/chip8.html">Matthew Mikolay's &quot;Mastering CHIP-8&quot;</a></li>
<li><a href="https://github.com/AfBu/haxe-CHIP-8-emulator/wiki/\(Super\)CHIP-8-Secrets">(Super)CHIP 8 Secrets</a></li>
</ul>
<h2 id="s3-the-main-data-structure"><a href="index.html#s3-the-main-data-structure">The Main Data Structure</a></h2>
<p>Let's dive into the code. We'll start with the main data structure that will
hold an instance of a CHIP-8 for emulation:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defstruct</span></i> chip
<span class="paren2">(<span class="code">running t <span class="keyword">:type</span> boolean</span>)</span>
<span class="comment">; ...more to come later
</span> </span>)</span></span></code></pre>
<p>We're using a Lisp struct instead of a CLOS class because we're going to be
accessing the fields of this thing <em>a lot</em> and CLOS accessors can be
comparatively slow. This is one of the very few concessions we'll make to
performance.</p>
<p>The first field is <code>running</code>, which is just a boolean that represents whether
the emulator is currently running.</p>
<p>We'll eventually have multiple threads poking at this struct, and they'll
generally be doing something like <code>(loop :while (chip-running chip) :do ...)</code>.
That way when we want to quit the emulator we can just set <code>running</code> to <code>nil</code>
and everything will (eventually) stop.</p>
<h3 id="s4-registers"><a href="index.html#s4-registers">Registers</a></h3>
<p>The CHIP-8 has sixteen main registers, as well as a few other special ones:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defstruct</span></i> chip
<span class="comment">; ...
</span> <span class="paren2">(<span class="code">registers <span class="paren3">(<span class="code">make-array 16 <span class="keyword">:element-type</span> 'int8</span>)</span>
<span class="keyword">:type</span> <span class="paren3">(<span class="code">simple-array int8 <span class="paren4">(<span class="code">16</span>)</span></span>)</span>
<span class="keyword">:read-only</span> t</span>)</span>
<span class="paren2">(<span class="code">index 0 <span class="keyword">:type</span> int16</span>)</span>
<span class="paren2">(<span class="code">program-counter #x200 <span class="keyword">:type</span> int12</span>)</span>
<span class="comment">; ...
</span> </span>)</span></span></code></pre>
<p>We'll keep the main registers in an array, and the others will just be separate
slots. I've added type declarations in the struct for two reasons:</p>
<ul>
<li>With a high <code>safety</code> declaration many implementations (including SBCL, the one
I'm using) will type check at runtime to make sure we're setting things
appropriately.</li>
<li>With low <code>safety</code> and high <code>speed</code> declarations, SBCL can generate much faster
code if it knows the types of the struct slots.</li>
</ul>
<p>To make the integer types a bit less wordy I've defined some simple synonyms:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">deftype</span></i> int4 <span class="paren2">(<span class="code"></span>)</span> '<span class="paren2">(<span class="code">unsigned-byte 4</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">deftype</span></i> int8 <span class="paren2">(<span class="code"></span>)</span> '<span class="paren2">(<span class="code">unsigned-byte 8</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">deftype</span></i> int12 <span class="paren2">(<span class="code"></span>)</span> '<span class="paren2">(<span class="code">unsigned-byte 12</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">deftype</span></i> int16 <span class="paren2">(<span class="code"></span>)</span> '<span class="paren2">(<span class="code">unsigned-byte 16</span>)</span></span>)</span></span></code></pre>
<p>So <code>registers</code> is a 16-element simple array of <code>(unsigned-byte 8)</code>s. It's
<code>read-only</code> because we'll be changing the <em>elements</em> of the array, but we should
never be swapping out the entire array itself.</p>
<p>The index register is 16 bits, and the program counter can store up to 12 bits
(we'll never need more than that because of the size of the CHIP-8's memory).</p>
<p>Also note that the program counter starts at address <code>#x200</code>, because that's
where the ROM data eventually gets loaded into the CHIP-8 memory.</p>
<h3 id="s5-the-stack"><a href="index.html#s5-the-stack">The Stack</a></h3>
<p>The CHIP-8 also has an internal stack to store return addresses when calling
procedures. We'll just use a Lisp vector with a fill pointer for this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defstruct</span></i> chip
<span class="comment">; ...
</span> <span class="paren2">(<span class="code">stack <span class="paren3">(<span class="code">make-array 16 <span class="keyword">:element-type</span> 'int12 <span class="keyword">:fill-pointer</span> 0</span>)</span>
<span class="keyword">:type</span> <span class="paren3">(<span class="code">vector int12 16</span>)</span>
<span class="keyword">:read-only</span> t</span>)</span>
<span class="comment">; ...
</span> </span>)</span></span></code></pre>
<h3 id="s6-memory"><a href="index.html#s6-memory">Memory</a></h3>
<p>The CHIP-8 has 4 kilobytes of main memory:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defconstant</span></i> +memory-size+ <span class="paren2">(<span class="code">* 1024 4</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defstruct</span></i> chip
<span class="comment">; ...
</span> <span class="paren2">(<span class="code">memory <span class="paren3">(<span class="code">make-array +memory-size+ <span class="keyword">:element-type</span> 'int8</span>)</span>
<span class="keyword">:type</span> <span class="paren3">(<span class="code">simple-array int8 <span class="paren4">(<span class="code">#.+memory-size+</span>)</span></span>)</span>
<span class="keyword">:read-only</span> t</span>)</span>
<span class="comment">; ...
</span> </span>)</span></span></code></pre>
<p>Pretty simple. Note the <code>#.</code> reader macro trick/hack to be able to use
a variable where we normally need a raw type specifier.</p>
<h3 id="s7-currently-loaded-rom"><a href="index.html#s7-currently-loaded-rom">Currently-Loaded ROM</a></h3>
<p>Finally we'll add a slot for keeping track of the path to the currently-loaded
ROM, for easy resetting later:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defstruct</span></i> chip
<span class="comment">; ...
</span> <span class="paren2">(<span class="code">loaded-rom nil <span class="keyword">:type</span> <span class="paren3">(<span class="code">or null string</span>)</span></span>)</span>
<span class="comment">; ...
</span> </span>)</span></span></code></pre>
<p>That's it for now. We'll need a few more slots once we get to things like
graphics and sound, but I'll introduce them when we need them.</p>
<h3 id="s8-the-flag-register"><a href="index.html#s8-the-flag-register">The Flag Register</a></h3>
<p>Register number 15, or <code>#xF</code> in hex, is special. It's nicknamed the &quot;flag&quot;
register and gets set specially by certain instructions. We could just access
it like the rest of the registers in our code:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">setf <span class="paren2">(<span class="code">aref <span class="paren3">(<span class="code">chip-registers chip</span>)</span> 15</span>)</span> 1</span>)</span> <span class="comment">; set flag to 1
</span><span class="paren1">(<span class="code">print <span class="paren2">(<span class="code">aref <span class="paren3">(<span class="code">chip-registers chip</span>)</span> #xF</span>)</span></span>)</span> <span class="comment">; print the flag</span></span></code></pre>
<p>But even with the <code>#xF</code> hex index to get that mnemonic &quot;F&quot; this is a bit too
hard to read. Let's define some extra reader and writer functions to clean
things up:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> chip-flag <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code">aref <span class="paren3">(<span class="code">chip-registers chip</span>)</span> #xF</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> <span class="paren2">(<span class="code">setf chip-flag</span>)</span> <span class="paren2">(<span class="code">new-value chip</span>)</span>
<span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">aref <span class="paren4">(<span class="code">chip-registers chip</span>)</span> #xF</span>)</span> new-value</span>)</span></span>)</span></span></code></pre>
<p><a href="https://github.com/sjl/cl-losh/blob/master/DOCUMENTATION.markdown#defun-inline-macro"><code>defun-inline</code></a> is from my utility library — it just <code>defun</code>s the
function and <code>declaim</code>s it inline all in one step. Now things are much nicer:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">setf <span class="paren2">(<span class="code">chip-flag chip</span>)</span> 1</span>)</span> <span class="comment">; set flag to 1
</span><span class="paren1">(<span class="code">print <span class="paren2">(<span class="code">chip-flag chip</span>)</span></span>)</span> <span class="comment">; print the flag</span></span></code></pre>
<h2 id="s9-removing-tedium"><a href="index.html#s9-removing-tedium">Removing Tedium</a></h2>
<p>What we've got so far <em>works</em>, but I want to add one more piece of syntactic
sugar before moving on.</p>
<p>We're going to be accessing the slots of the <code>chip</code> struct a <em>lot</em>, and it's
going to get tedious to write <code>(chip-SLOT chip)</code> over and over again. For
example, when we're resetting the emulator we'll have to do something like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> reset <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code">fill <span class="paren3">(<span class="code">chip-memory chip</span>)</span> 0</span>)</span>
<span class="paren2">(<span class="code">fill <span class="paren3">(<span class="code">chip-registers chip</span>)</span> 0</span>)</span>
<span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">chip-running chip</span>)</span> t
<span class="paren3">(<span class="code">chip-program-counter chip</span>)</span> #x200
<span class="paren3">(<span class="code">fill-pointer <span class="paren4">(<span class="code">chip-stack chip</span>)</span></span>)</span> 0</span>)</span></span>)</span></span></code></pre>
<p>This is annoying. Languages like Javascript and Python use <code>.</code> for slot
access, so it ends up being a bit more concise: <code>chip.memory()</code> instead of
<code>(chip-memory chip)</code>.</p>
<p>We could use Lisp's <code>with-accessors</code> to clean up the actual usage a bit:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> reset <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">with-accessors</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">memory chip-memory</span>)</span>
<span class="paren4">(<span class="code">registers chip-registers</span>)</span>
<span class="paren4">(<span class="code">running chip-running</span>)</span>
<span class="paren4">(<span class="code">program-counter chip-program-counter</span>)</span>
<span class="paren4">(<span class="code">stack chip-stack</span>)</span></span>)</span>
chip
<span class="paren3">(<span class="code">fill memory 0</span>)</span>
<span class="paren3">(<span class="code">fill registers 0</span>)</span>
<span class="paren3">(<span class="code">setf running t
program-counter #x200
<span class="paren4">(<span class="code">fill-pointer stack</span>)</span> 0</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>The <em>usage</em> looks much nicer now (<code>(fill memory 0)</code> is wonderfully readable) but
we haven't actually fixed anything. We've just shifted all the typing a few
lines up. But this is Lisp, we can do better!</p>
<p>Ideally what we'd like is to be able to do say something like <code>(with-chip (chip)
...)</code> to mean the giant <code>with-accessors</code> form above:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> reset <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren3">(<span class="code">chip</span>)</span>
<span class="paren3">(<span class="code">fill memory 0</span>)</span>
<span class="paren3">(<span class="code">fill registers 0</span>)</span>
<span class="paren3">(<span class="code">setf running t
program-counter #x200
<span class="paren4">(<span class="code">fill-pointer stack</span>)</span> 0</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This is nice and readable. Some folks will dislike the fact that it introduces
new variable bindings that are &quot;hidden&quot; in the macro definition, but I like the
concision you get from it, especially for a small project like this.</p>
<p>We could write <code>with-chip</code> ourselves, if we wanted to. It would look something
like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> <i><span class="symbol">with-chip</span></i> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">chip</span>)</span> &amp;body body</span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">with-accessors</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">memory chip-memory</span>)</span>
<span class="paren4">(<span class="code">registers chip-registers</span>)</span>
<span class="comment">; ...
</span> </span>)</span>
,chip
,@body</span>)</span>`
</span>)</span></span></code></pre>
<p>It's not hard to write, just tedious. But we're using Lisp, so anything tedious
calls out for abstraction. Another macro from my utility library is
<a href="https://github.com/sjl/cl-losh/blob/master/DOCUMENTATION.markdown#define-with-macro-macro"><code>define-with-macro</code></a>. This is a macro-defining macro that
we can use to define <code>with-chip</code> for us:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-with-macro</span></i> chip
running memory stack registers index program-counter flag</span>)</span></span></code></pre>
<p>If the hairiness of a macro-defining macro scares you, don't worry about it. We
could have just written it by hand as shown above. I've just needed <code>with-FOO</code>
macros like these often enough that it's been worth it to abstract away the
tedium of writing them.</p>
<p>So one way or another we've got a nice <code>with-chip</code> macro that will let us access
the fields of our struct with bare names.</p>
<h2 id="s10-infrastructure"><a href="index.html#s10-infrastructure">Infrastructure</a></h2>
<p>We'll need to define a bit of infrastructure for running things before we jump
into implementing the CHIP-8 CPU instructions.</p>
<h3 id="s11-resetting"><a href="index.html#s11-resetting">Resetting</a></h3>
<p>Before we can emulate a ROM, we need to read it into our memory array. I've
chosen to do this in the <code>reset</code> function so we can just <code>(reset my-chip)</code> to
reload everything at once — it wouldn't make much sense to load a new ROM
<em>without</em> resetting the rest of the emulation state (though the results could
be... &quot;interesting&quot;).</p>
<p><code>reset</code> looks like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> reset <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren3">(<span class="code">chip</span>)</span>
<span class="paren3">(<span class="code">fill memory 0</span>)</span>
<span class="paren3">(<span class="code">fill registers 0</span>)</span>
<span class="paren3">(<span class="code">replace memory <span class="paren4">(<span class="code">read-file-into-byte-vector loaded-rom</span>)</span>
<span class="keyword">:start1</span> #x200</span>)</span>
<span class="paren3">(<span class="code">setf running t
program-counter #x200
<span class="paren4">(<span class="code">fill-pointer stack</span>)</span> 0</span>)</span></span>)</span>
<span class="paren2">(<span class="code">values</span>)</span></span>)</span></span></code></pre>
<p>This is pretty self explanatory, except for the actual ROM-loading bit:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">replace memory <span class="paren2">(<span class="code">read-file-into-byte-vector loaded-rom</span>)</span>
<span class="keyword">:start1</span> #x200</span>)</span></span></code></pre>
<p><code>replace</code> is just the standard Common Lisp <code>replace</code> function that copies the
contents of one sequence into another. <code>read-file-into-byte-vector</code> is from
Alexandria, and will just read the file at <code>loaded-rom</code> into a byte vector.
Then all we need to do is say that we want to start the copying at index <code>#x200</code>
in the destination, because that's where the CHIP-8 ROM data is supposed start
(there's other internal data (like font sprites) before it, which we'll see
later).</p>
<p>One last thing to note is that <code>reset</code> just returns <code>(values)</code>, i.e. it returns
nothing at all. This is something I sometimes do for functions I call at the
REPL for side effects, to avoid returning a meaningless result. I think of it
as an application of <a href="http://www.linfo.org/rule_of_silence.html">The Rule of Silence</a> for Lisp.</p>
<h3 id="s12-loading-roms"><a href="index.html#s12-loading-roms">Loading ROMs</a></h3>
<p>Now that we've got a reset function, it's trivial to define a function to load
a new ROM into our emulator:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> load-rom <span class="paren2">(<span class="code">chip filename</span>)</span>
<span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">chip-loaded-rom chip</span>)</span> filename</span>)</span>
<span class="paren2">(<span class="code">reset chip</span>)</span></span>)</span></span></code></pre>
<p>I didn't bother with the <code>with-chip</code> macro here because we're only accessing
a single field.</p>
<h3 id="s13-the-main-loop-s"><a href="index.html#s13-the-main-loop-s">The Main Loop(s)</a></h3>
<p>Now let's wrap things up into a nice interface. We'll define a top-level <code>run</code>
function that will be what we call to fire up the emulator:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defparameter</span></i> <span class="special">*c*</span> nil</span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> run <span class="paren2">(<span class="code">rom-filename</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">chip <span class="paren5">(<span class="code">make-chip</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">setf <span class="special">*c*</span> chip</span>)</span>
<span class="paren3">(<span class="code">load-rom chip rom-filename</span>)</span>
<span class="paren3">(<span class="code">run-cpu chip</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This will get more complicated in the future, but for now it's pretty simple.
Make a new <code>chip</code> object, load the specified ROM, and start emulating.</p>
<p>I've added a <code>*c*</code> global variable that's bound to the currently-running
emulator so we can poke at it in NREPL or SLIME as it's running.</p>
<p>Now to write <code>run-cpu</code>:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defconstant</span></i> +cycles-per-second+ 500</span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defconstant</span></i> +cycles-before-sleep+ 10</span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> run-cpu <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code">iterate
<span class="paren3">(<span class="code">while <span class="paren4">(<span class="code">chip-running chip</span>)</span></span>)</span>
<span class="paren3">(<span class="code">emulate-cycle chip</span>)</span>
<span class="paren3">(<span class="code">for tick <span class="keyword">:every-nth</span> +cycles-before-sleep+ <span class="keyword">:do</span>
<span class="paren4">(<span class="code">sleep <span class="paren5">(<span class="code">/ +cycles-before-sleep+ +cycles-per-second+</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>CHIP-8 was designed to run on much weaker hardware than we have these days.
Even though we're emulating it, if we just run as fast as possible we'll be
running <em>far</em> too fast to be playable.</p>
<p><code>+cycles-per-second+</code> is a constant describing our ideal emulation speed.
Anything from 300 to 800 or so is playable, depending on how fast you want games
to run. We'll just use 500 for now as a happy medium.</p>
<p>It would be wasteful to call <code>(sleep)</code> after every single cycle, so instead
we'll batch them together: run 10 instructions, sleep for a bit, repeat. This
is the job of the <code>(for ... every-nth N)</code> iterate driver, which is also in my
utility library. Every 10 iterations through the loop it will sleep for the
appropriate amount of time.</p>
<p>The size of the cycle batches is arbitrary — larger batches will result in fewer
<code>(sleep)</code> calls, but if you go too large you'll start noticing the emulator
getting &quot;jumpy&quot;. 10-cycle batches at 500 cycles per second means that the
emulator will sleep for about 1/50 of a second each time, which isn't too
noticeable.</p>
<p>Now we've got the main loop all set up and just need to emulate each individual
cycle.</p>
<h3 id="s14-individual-cycles"><a href="index.html#s14-individual-cycles">Individual Cycles</a></h3>
<p>CHIP-8 instructions are each two bytes long, and are stored
<a href="https://en.wikipedia.org/wiki/Endianness">big-endian</a> in memory. So to emulate
a single cycle we:</p>
<ul>
<li>Read the two bytes starting at the program counter and concatenate them to get the instruction.</li>
<li>Advance the program counter (to avoid having to do it inside every single instruction).</li>
<li>Dispatch to the appropriate instruction code.</li>
</ul>
<p>We'll define <code>emulate-cycle</code> and a couple of helper functions for this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> chop <span class="paren2">(<span class="code">size integer</span>)</span>
<span class="paren2">(<span class="code">ldb <span class="paren3">(<span class="code">byte size 0</span>)</span> integer</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> cat-bytes <span class="paren2">(<span class="code">high-order low-order</span>)</span>
<span class="paren2">(<span class="code">dpb high-order <span class="paren3">(<span class="code">byte 8 8</span>)</span> low-order</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> emulate-cycle <span class="paren2">(<span class="code">chip</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren3">(<span class="code">chip</span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">instruction <span class="paren6">(<span class="code">cat-bytes <span class="paren1">(<span class="code">aref memory program-counter</span>)</span>
<span class="paren1">(<span class="code">aref memory <span class="paren2">(<span class="code">1+ program-counter</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">zapf program-counter <span class="paren5">(<span class="code">chop 12 <span class="paren6">(<span class="code">+ % 2</span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">dispatch-instruction chip instruction</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p><code>chop</code> truncates an integer to the given number of bits. <code>cat-bytes</code>
concatenates two bytes. These are pretty simple, but I prefer the more
descriptive names over writing <code>dpb</code> (deposit byte) and <code>ldb</code> (load byte)
everywhere.</p>
<p><code>zapf</code> is from my utility library. I've written <a href="../../08/playing-with-syntax/index.html">an entire post</a> about
it.</p>
<p>What happens when the program counter is at the final index into memory? None
of the CHIP-8 references I found specify what should happen. We could signal an
error, or just wrap around to 0. I've chosen the latter by chopping <code>(+
program-counter 2)</code> to 12 bits, but signaling an error would be easy too.</p>
<h3 id="s15-instruction-dispatch"><a href="index.html#s15-instruction-dispatch">Instruction Dispatch</a></h3>
<p>The CHIP-8's instruction scheme is a bit different than most others that I've
seen.</p>
<p>For systems like the Game Boy instructions have a one- or two-byte opcode, with
arguments following. For systems like this you can dispatch on opcode by doing
a giant <code>case</code> statement:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">case opcode
<span class="paren2">(<span class="code">#x00 <span class="paren3">(<span class="code">op-foo ...</span>)</span></span>)</span>
<span class="paren2">(<span class="code">#x01 <span class="paren3">(<span class="code">op-bar ...</span>)</span></span>)</span>
<span class="comment">; ...
</span> </span>)</span></span></code></pre>
<p>But a more efficient way to do it is often to shove all the <code>op-</code> functions into
an array, and then just use the opcode itself as the index into the array to
find the function:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">funcall <span class="paren2">(<span class="code">aref opcodes opcode</span>)</span> ...</span>)</span></span></code></pre>
<p>But the CHIP-8 differentiates instructions a bit strangely. All instructions
are two bytes long, <em>including</em> their arguments. Instead of just using the
first N bits as the opcode, some instructions use a combination of high- and
low-order bits. For example, the logical <code>AND</code>, <code>OR</code>, and <code>XOR</code> are specified
by starting the instruction with an <code>8</code> nibble and ending it with <code>1</code>, <code>2</code>, or
<code>3</code>, with the &quot;arguments&quot; being the two nibbles in the middle:</p>
<pre><code>8xy1 - OR Vx, Vy
8xy2 - AND Vx, Vy
8xy3 - XOR Vx, Vy
</code></pre>
<p>This makes it rather annoying to use some kind of function table approach.
There are only a few dozen opcodes, so instead of trying to hack something
together we'll just use a big old <code>case</code> instead:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> dispatch-instruction <span class="paren2">(<span class="code">chip instruction</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">macrolet</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">call <span class="paren5">(<span class="code">name</span>)</span> `<span class="paren5">(<span class="code">,name chip instruction</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">ecase <span class="paren4">(<span class="code">logand #xF000 instruction</span>)</span>
<span class="paren4">(<span class="code">#x0000 <span class="paren5">(<span class="code">ecase instruction
<span class="paren6">(<span class="code">#x00E0 <span class="paren1">(<span class="code">call op-cls</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x00EE <span class="paren1">(<span class="code">call op-ret</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x1000 <span class="paren5">(<span class="code">call op-jp-imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x2000 <span class="paren5">(<span class="code">call op-call</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x3000 <span class="paren5">(<span class="code">call op-se-reg-imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x4000 <span class="paren5">(<span class="code">call op-sne-reg-imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x5000 <span class="paren5">(<span class="code">ecase <span class="paren6">(<span class="code">logand #x000F instruction</span>)</span>
<span class="paren6">(<span class="code">#x0 <span class="paren1">(<span class="code">call op-se-reg-reg</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x6000 <span class="paren5">(<span class="code">call op-ld-reg&lt;imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x7000 <span class="paren5">(<span class="code">call op-add-reg&lt;imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x8000 <span class="paren5">(<span class="code">ecase <span class="paren6">(<span class="code">logand #x000F instruction</span>)</span>
<span class="paren6">(<span class="code">#x0 <span class="paren1">(<span class="code">call op-ld-reg&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x1 <span class="paren1">(<span class="code">call op-or</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x2 <span class="paren1">(<span class="code">call op-and</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x3 <span class="paren1">(<span class="code">call op-xor</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x4 <span class="paren1">(<span class="code">call op-add-reg&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x5 <span class="paren1">(<span class="code">call op-sub-reg&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x6 <span class="paren1">(<span class="code">call op-shr</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x7 <span class="paren1">(<span class="code">call op-subn-reg&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#xE <span class="paren1">(<span class="code">call op-shl</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">#x9000 <span class="paren5">(<span class="code">ecase <span class="paren6">(<span class="code">logand #x000F instruction</span>)</span>
<span class="paren6">(<span class="code">#x0 <span class="paren1">(<span class="code">call op-sne-reg-reg</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xA000 <span class="paren5">(<span class="code">call op-ld-i&lt;imm</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xB000 <span class="paren5">(<span class="code">call op-jp-imm+reg</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xC000 <span class="paren5">(<span class="code">call op-rand</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xD000 <span class="paren5">(<span class="code">call op-draw</span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xE000 <span class="paren5">(<span class="code">ecase <span class="paren6">(<span class="code">logand #x00FF instruction</span>)</span>
<span class="paren6">(<span class="code">#x9E <span class="paren1">(<span class="code">call op-skp</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#xA1 <span class="paren1">(<span class="code">call op-sknp</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren4">(<span class="code">#xF000 <span class="paren5">(<span class="code">ecase <span class="paren6">(<span class="code">logand #x00FF instruction</span>)</span>
<span class="paren6">(<span class="code">#x07 <span class="paren1">(<span class="code">call op-ld-reg&lt;dt</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x0A <span class="paren1">(<span class="code">call op-ld-reg&lt;key</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x15 <span class="paren1">(<span class="code">call op-ld-dt&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x18 <span class="paren1">(<span class="code">call op-ld-st&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x1E <span class="paren1">(<span class="code">call op-add-index&lt;reg</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x29 <span class="paren1">(<span class="code">call op-ld-font&lt;vx</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x33 <span class="paren1">(<span class="code">call op-ld-bcd&lt;vx</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x55 <span class="paren1">(<span class="code">call op-ld-mem&lt;regs</span>)</span></span>)</span>
<span class="paren6">(<span class="code">#x65 <span class="paren1">(<span class="code">call op-ld-regs&lt;mem</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>The <code>macrolet</code> at the beginning saves us a bit of typing, but otherwise this is
just a big boring table to figure out which instruction to call.</p>
<p>That's all the boring infrastructure work we need — on to implementing the
actual instructions.</p>
<h2 id="s16-instructions"><a href="index.html#s16-instructions">Instructions</a></h2>
<p>The CHIP-8 supports thirty-six instructions, all of which we'll need to
implement. We'll start with the simpler ones, and we'll be leaving some of the
others (the graphics/sound related ones) for later articles.</p>
<p>(In contrast, the Game Boy has roughly five hundred instructions, so now you
might see why I thought CHIP-8 would be simpler!)</p>
<h3 id="s17-random-numbers"><a href="index.html#s17-random-numbers">Random Numbers</a></h3>
<p>We'll start with the <code>RND</code> instruction, which generates random numbers. This
may seem like an odd place to start, but I want to describe some extra syntactic
sugar and <code>RND</code> is a nice standalone instruction to use as an example.</p>
<p>Cowgod's reference describes <code>RND</code> like so:</p>
<pre><code>Cxkk - RND Vx, byte
Set Vx = random byte AND kk.
The interpreter generates a random number from 0 to 255,
which is then ANDed with the value kk. The results are
stored in Vx.
</code></pre>
<p>A first stab at the implementation in Lisp might look like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> op-rand <span class="paren2">(<span class="code">chip instruction</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">reg <span class="paren5">(<span class="code">logand #x0F00 instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code">mask <span class="paren5">(<span class="code">logand #x00FF instruction</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren4">(<span class="code">chip</span>)</span>
<span class="paren4">(<span class="code">setf <span class="paren5">(<span class="code">aref registers reg</span>)</span>
<span class="paren5">(<span class="code">logand <span class="paren6">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This would work, but it's an awful lot of code for something that just takes
a sentence or two to describe. We're going to be defining a lot of
instructions, so let's take a few minutes and make our lives easier.</p>
<h3 id="s18-define-instruction"><a href="index.html#s18-define-instruction">Define-Instruction</a></h3>
<p>We'll create a <code>define-instruction</code> macro that will abstract away some of the
boring bits. The goal is to end up with instruction definitions that read as
close to the documentation as possible.</p>
<p>We'll start by removing the need to use the <code>with-chip</code> macro. Every
instruction needs to deal with the <code>chip</code> struct, so let's not repeat ourselves
thirty-six times. Every instruction will also take <code>chip</code> and <code>instruction</code>
arguments, so we can remove those too:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> <i><span class="symbol">define-instruction</span></i> <span class="paren2">(<span class="code">name &amp;body body</span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">defun</span></i> ,name <span class="paren3">(<span class="code">chip instruction</span>)</span>
<span class="paren3">(<span class="code">declare <span class="paren4">(<span class="code">ignorable instruction</span>)</span></span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren4">(<span class="code">chip</span>)</span>
,@body</span>)</span>
nil</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-rand
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">reg <span class="paren5">(<span class="code">logand #x0F00 instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code">mask <span class="paren5">(<span class="code">logand #x00FF instruction</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">setf <span class="paren4">(<span class="code">aref registers reg</span>)</span>
<span class="paren4">(<span class="code">logand <span class="paren5">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>That's a little better. We're going to be calling these instructions a <em>lot</em>,
so it wouldn't hurt to add a type declaration for each function. This is easy
because they all take and return the same types:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> <i><span class="symbol">define-instruction</span></i> <span class="paren2">(<span class="code">name &amp;body body</span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">progn</span></i>
<span class="paren3">(<span class="code">declaim <span class="paren4">(<span class="code">ftype <span class="paren5">(<span class="code"><i><span class="symbol">function</span></i> <span class="paren6">(<span class="code">chip int16</span>)</span> null</span>)</span> ,name</span>)</span></span>)</span> <span class="comment">; NEW
</span> <span class="paren3">(<span class="code"><i><span class="symbol">defun</span></i> ,name <span class="paren4">(<span class="code">chip instruction</span>)</span>
<span class="paren4">(<span class="code">declare <span class="paren5">(<span class="code">ignorable instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren5">(<span class="code">chip</span>)</span>
,@body</span>)</span>
nil</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Now all of our instruction functions will have type hints, and SBCL can check
them (if <code>safety</code> is high) or use them to generate faster code (if <code>speed</code> is
high).</p>
<p>We'll be accessing the values of registers quite often (<code>(aref registers ...)</code>)
so let's add a little <code>macrolet</code> to make that read nicer:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> <i><span class="symbol">define-instruction</span></i> <span class="paren2">(<span class="code">name &amp;body body</span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">progn</span></i>
<span class="paren3">(<span class="code">declaim <span class="paren4">(<span class="code">ftype <span class="paren5">(<span class="code"><i><span class="symbol">function</span></i> <span class="paren6">(<span class="code">chip int16</span>)</span> null</span>)</span> ,name</span>)</span></span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">defun</span></i> ,name <span class="paren4">(<span class="code">chip instruction</span>)</span>
<span class="paren4">(<span class="code">declare <span class="paren5">(<span class="code">ignorable instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren5">(<span class="code">chip</span>)</span>
<span class="paren5">(<span class="code"><i><span class="symbol">macrolet</span></i> <span class="paren6">(<span class="code"><span class="paren1">(<span class="code">register <span class="paren2">(<span class="code">index</span>)</span> <span class="comment">; NEW
</span> `<span class="paren2">(<span class="code">aref registers ,index</span>)</span></span>)</span></span>)</span> <span class="comment">; NEW
</span> ,@body</span>)</span></span>)</span>
nil</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-rand
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">reg <span class="paren5">(<span class="code">logand #x0F00 instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code">mask <span class="paren5">(<span class="code">logand #x00FF instruction</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">setf <span class="paren4">(<span class="code">register reg</span>)</span> <span class="comment">; NEW
</span> <span class="paren4">(<span class="code">logand <span class="paren5">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Now instead of <code>(aref registers ...)</code> we can just say <code>(register ...)</code>. Cool.</p>
<p>The one thing that still bothers me is having to manually pull the instruction
arguments out of the instruction with bitmasking. It would be much nicer if we
could just declare what the arguments look like and have the computer generate
the appropriate masking code to deal with them. The goal is to be able to write
something like this:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-rand <span class="paren2">(<span class="code">_ r <span class="paren3">(<span class="code">mask 2</span>)</span></span>)</span> <span class="comment">;; RND
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">register r</span>)</span>
<span class="paren3">(<span class="code">logand <span class="paren4">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>The <code>(_ r (mask 2))</code> is the &quot;argument list&quot; of the instruction. It says:</p>
<ul>
<li>A single-nibble value which we don't care about: <code>_</code></li>
<li>A single-nibble value should be bound to <code>r</code>: <code>r</code></li>
<li>A two-nibble value should be bound to <code>mask</code>: <code>(mask 2)</code></li>
</ul>
<p>Compare the Lisp code and Cowgod's documentation:</p>
<pre><code>Cxkk - RND Vx, byte
Set Vx = random byte AND kk.
(define-instruction op-rand (_ r (mask 2)) ;; RND
(setf (register r)
(logand (random 256) mask)))</code></pre>
<p>Cowgod uses <code>V</code> as a shorthand for <code>register</code>, and calls the argument <code>x</code>
instead of <code>r</code>, but otherwise I think this is pretty damn close to the
documentation for actual running code.</p>
<p>So let's implement the argument-parsing macro. Feel free to skip this if you're
not really comfortable with macros. But it's a good demonstration of how you
can use them to get a nice clean language for a simple project.</p>
<p>First we'll wrap the <code>body</code> in a <code>let</code>:</p>
<pre><code><span class="code"> <span class="comment">; NEW
</span><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> <i><span class="symbol">define-instruction</span></i> <span class="paren2">(<span class="code">name argument-list &amp;body body</span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">progn</span></i>
<span class="paren3">(<span class="code">declaim <span class="paren4">(<span class="code">ftype <span class="paren5">(<span class="code"><i><span class="symbol">function</span></i> <span class="paren6">(<span class="code">chip int16</span>)</span> null</span>)</span> ,name</span>)</span></span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">defun</span></i> ,name <span class="paren4">(<span class="code">chip instruction</span>)</span>
<span class="paren4">(<span class="code">declare <span class="paren5">(<span class="code">ignorable instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren5">(<span class="code">chip</span>)</span>
<span class="paren5">(<span class="code"><i><span class="symbol">macrolet</span></i> <span class="paren6">(<span class="code"><span class="paren1">(<span class="code">register <span class="paren2">(<span class="code">index</span>)</span>
`<span class="paren2">(<span class="code">aref registers ,index</span>)</span></span>)</span></span>)</span>
<span class="paren6">(<span class="code"><i><span class="symbol">let</span></i> ,<span class="paren1">(<span class="code">parse-instruction-argument-bindings argument-list</span>)</span> <span class="comment">; NEW
</span> ,@body</span>)</span></span>)</span>
nil</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>We'll use a helper function to parse the argument list into a list of <code>let</code>
bindings, instead of trying to cram it all into this one macro. It might look
scary, but it's not actually too bad:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> parse-instruction-argument-bindings <span class="paren2">(<span class="code">argument-list</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">flet</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">normalize-arg <span class="paren5">(<span class="code">arg</span>)</span>
<span class="paren5">(<span class="code">destructuring-bind <span class="paren6">(<span class="code">symbol &amp;optional <span class="paren1">(<span class="code">nibbles 1</span>)</span></span>)</span>
<span class="paren6">(<span class="code">ensure-list arg</span>)</span>
<span class="paren6">(<span class="code">list symbol nibbles</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">iterate
<span class="paren4">(<span class="code">for <span class="paren5">(<span class="code">symbol nibbles</span>)</span> <span class="keyword">:in</span> <span class="paren5">(<span class="code">mapcar #'normalize-arg argument-list</span>)</span></span>)</span>
<span class="paren4">(<span class="code">for position <span class="keyword">:first</span> 3 <span class="keyword">:then</span> <span class="paren5">(<span class="code">- position nibbles</span>)</span></span>)</span>
<span class="paren4">(<span class="code">when <span class="paren5">(<span class="code">not <span class="paren6">(<span class="code">eql symbol '_</span>)</span></span>)</span>
<span class="paren5">(<span class="code">collect `<span class="paren6">(<span class="code">,symbol <span class="paren1">(<span class="code">ldb <span class="paren2">(<span class="code">byte ,<span class="paren3">(<span class="code">* nibbles 4</span>)</span>
,<span class="paren3">(<span class="code">* position 4</span>)</span></span>)</span>
instruction</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p><code>normalize-arg</code> takes each argument from the list and turns it into <code>(symbol
nibbles)</code>, so we don't have to write the lengths for single-nibble arguments
like this: <code>((_ 1) (r 1) (mask 2))</code>.</p>
<p>Then we loop through each <code>(symbol nibbles)</code> pair in the argument list. We
start at position <code>3</code> in the byte (the highest-order nibble) because we want to
write the argument list from left to right, high-order to low-order, like the
documentation.</p>
<p>For each pair, if the symbol is anything other than <code>_</code> we collect a <code>let</code>
binding with the appropriate <code>ldb</code> call for it. So for our example of <code>(_
r (mask 2))</code> we end up with two <code>let</code> bindings:</p>
<ul>
<li><code>(r (ldb (byte 4 8) instruction))</code></li>
<li><code>(mask (ldb (byte 8 0) instruction))</code></li>
</ul>
<p>Notice that we only bother parsing out the bindings we <em>need</em> from the
instruction. For instructions that don't need any arguments we'll end up with
an empty <code>(let () ...)</code> which the compiler will optimize away.</p>
<p>This might seem a bit hairy. The nice thing about using a helper function like
this is that we can call it on its own with a variety of argument lists to see
what gets generated:</p>
<pre><code>(map nil #'print
(parse-instruction-argument-bindings '(_ r (mask 2))))
(R (LDB (BYTE 4 8) INSTRUCTION))
(MASK (LDB (BYTE 8 0) INSTRUCTION))
(map nil #'print
(parse-instruction-argument-bindings '(_ x y _)))
(X (LDB (BYTE 4 8) INSTRUCTION))
(Y (LDB (BYTE 4 4) INSTRUCTION))
(map nil #'print
(parse-instruction-argument-bindings '(_ (foo 3))))
(FOO (LDB (BYTE 12 0) INSTRUCTION))</code></pre>
<p>And that wraps up <code>define-instruction</code>. So instead of writing <code>RND</code> as
a vanilla function:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun</span></i> op-rand <span class="paren2">(<span class="code">chip instruction</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">reg <span class="paren5">(<span class="code">logand #x0F00 instruction</span>)</span></span>)</span>
<span class="paren4">(<span class="code">mask <span class="paren5">(<span class="code">logand #x00FF instruction</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code"><i><span class="symbol">with-chip</span></i> <span class="paren4">(<span class="code">chip</span>)</span>
<span class="paren4">(<span class="code">setf <span class="paren5">(<span class="code">aref registers reg</span>)</span>
<span class="paren5">(<span class="code">logand <span class="paren6">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>We can do something much cleaner:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-rand <span class="paren2">(<span class="code">_ r <span class="paren3">(<span class="code">mask 2</span>)</span></span>)</span> <span class="comment">;; RND
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">register r</span>)</span>
<span class="paren3">(<span class="code">logand <span class="paren4">(<span class="code">random 256</span>)</span> mask</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This is going to pay off nicely as we implement the other thirty-five
instructions.</p>
<h3 id="s19-jumps-and-calls"><a href="index.html#s19-jumps-and-calls">Jumps and Calls</a></h3>
<p>The CHIP-8 has two instructions for jumping directly to an address. The first
jumps to an immediate, literal address. The second adds an immediate value to
whatever is in register <code>#x0</code> and jumps to the result:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-jp-imm <span class="paren2">(<span class="code">_ <span class="paren3">(<span class="code">target 3</span>)</span></span>)</span> <span class="comment">;; JP addr
</span> <span class="paren2">(<span class="code">setf program-counter target</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-jp-imm+reg <span class="paren2">(<span class="code">_ <span class="paren3">(<span class="code">target 3</span>)</span></span>)</span> <span class="comment">;; JP V0 + addr
</span> <span class="paren2">(<span class="code">setf program-counter <span class="paren3">(<span class="code">chop 12 <span class="paren4">(<span class="code">+ target <span class="paren5">(<span class="code">register 0</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Our <code>define-instruction</code> macro is already paying off. The immediate values of
these arguments are three nibbles each, but our macro doesn't care.</p>
<p>There are also two instructions for implementing traditional function calls and
returns using the CHIP-8's stack:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-call <span class="paren2">(<span class="code">_ <span class="paren3">(<span class="code">target 3</span>)</span></span>)</span> <span class="comment">;; CALL addr
</span> <span class="paren2">(<span class="code">vector-push program-counter stack</span>)</span>
<span class="paren2">(<span class="code">setf program-counter target</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-ret <span class="paren2">(<span class="code"></span>)</span> <span class="comment">;; RET
</span> <span class="paren2">(<span class="code">setf program-counter <span class="paren3">(<span class="code">vector-pop stack</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>We just use the built in <code>vector-push</code> and <code>vector-pop</code> functions to manage the
stack's fill pointer trivially.</p>
<p>Note that we're NOT using <code>vector-push-extend</code> because the CHIP-8 stack is
defined by the spec to only hold at most sixteen addresses — any ROM that tries
to push more is broken.</p>
<h3 id="s20-binary-coded-decimal"><a href="index.html#s20-binary-coded-decimal">Binary-Coded Decimal</a></h3>
<p>Let's take another self-contained instruction next: <code>BCD</code>, which stands for
<a href="https://en.wikipedia.org/wiki/Binary-coded_decimal">binary-coded decimal</a> (some references call this instruction <code>LD B, Vx</code>
but I think it's different enough to deserve its own name).</p>
<p>The problem this instruction is designed to solve goes something like this.
Let's say you've got a game where the player has a score that changes over time.
You can store the player's score in a register or memory somewhere, and
add/subtract to/from it with the normal arithmetic opcodes no problem.</p>
<p>But now you want to <em>display</em> the score to the player, and you probably want to
do that in base 10 because humans are generally bad at reading binary or hex.
So how do you take a byte like <code>#xA5</code> and determine the hundreds, tens, and ones
sprites to draw on the screen to read &quot;165 points&quot;?</p>
<p>This is what the <code>BCD</code> instruction does. It takes a single argument (the
register) and stores the hundreds, tens, and ones digits of that register's
value into three separate bytes of memory, starting at wherever the <code>index</code>
register is currently pointing.</p>
<pre class="lineart">
Register V3 Index Register
┌───┐ ┌───┐
│135│ │...│
└───┘ └─┬─┘
┌─────────────┘
┌───┬───┬───┬───┬───┐
│ │ │ │ │ │ Memory
└───┴───┴───┴───┴───┘
Run BCD V3 instruction =================
Register V3 Index Register
┌───┐ ┌───┐
│135│ │...│
└───┘ └─┬─┘
┌─────────────┘
┌───┬───┬───┬───┬───┐
│ 1 │ 3 │ 5 │ │ │ Memory
└───┴───┴───┴───┴───┘
</pre>
<p>We'll split this into two parts to make it easier to read. First we'll make
a <code>digit</code> function to retrieve a digit of a number:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> digit <span class="paren2">(<span class="code">position integer &amp;optional <span class="paren3">(<span class="code">base 10</span>)</span></span>)</span>
<span class="paren2">(<span class="code">-&lt;&gt; integer
<span class="paren3">(<span class="code">floor &lt;&gt; <span class="paren4">(<span class="code">expt base position</span>)</span></span>)</span>
<span class="paren3">(<span class="code">mod &lt;&gt; base</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>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.</p>
<p>Let's make sure it works on its own:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">digit 0 135</span>)</span>
5
<span class="paren1">(<span class="code">digit 1 135</span>)</span>
3
<span class="paren1">(<span class="code">digit 2 135</span>)</span>
1
<span class="paren1">(<span class="code">digit 0 #xD6 16</span>)</span>
6
<span class="paren1">(<span class="code">digit 1 #xD6 16</span>)</span>
13 <span class="comment">; 13 in base 10 == D in base 16</span></span></code></pre>
<p>And then we can define the actual operation:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-ld-bcd&lt;vx <span class="paren2">(<span class="code">_ r _ _</span>)</span> <span class="comment">;; LD B, Vx
</span> <span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">number <span class="paren5">(<span class="code">register r</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">setf <span class="paren4">(<span class="code">aref memory <span class="paren5">(<span class="code">+ index 0</span>)</span></span>)</span> <span class="paren4">(<span class="code">digit 2 number</span>)</span>
<span class="paren4">(<span class="code">aref memory <span class="paren5">(<span class="code">+ index 1</span>)</span></span>)</span> <span class="paren4">(<span class="code">digit 1 number</span>)</span>
<span class="paren4">(<span class="code">aref memory <span class="paren5">(<span class="code">+ index 2</span>)</span></span>)</span> <span class="paren4">(<span class="code">digit 0 number</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<h3 id="s21-arithmetic"><a href="index.html#s21-arithmetic">Arithmetic</a></h3>
<p>Next up are the arithmetic instructions. The CHIP-8 only supports addition and
subtraction — there are no multiplication or division instructions.</p>
<p>The first two instructions are <code>ADD</code> and <code>SUB</code>:</p>
<pre><code>ADD Vx, Vy → Vx = Vx + Vy
SUB Vx, Vy → Vx = Vx - Vy
</code></pre>
<p>Once again we'll start by creating two helper functions to perform the 8-bit
addition/subtraction with overflow/underflow. These functions will return
a second value that represents the carry/borrow bit.</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> +_8 <span class="paren2">(<span class="code">x y</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">result <span class="paren5">(<span class="code">+ x y</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">chop 8 result</span>)</span>
<span class="paren4">(<span class="code"><i><span class="symbol">if</span></i> <span class="paren5">(<span class="code">&gt; result 255</span>)</span> 1 0</span>)</span></span>)</span></span>)</span></span>)</span> <span class="comment">; carry
</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> -_8 <span class="paren2">(<span class="code">x y</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">let</span></i> <span class="paren3">(<span class="code"><span class="paren4">(<span class="code">result <span class="paren5">(<span class="code">- x y</span>)</span></span>)</span></span>)</span>
<span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">chop 8 result</span>)</span>
<span class="paren4">(<span class="code"><i><span class="symbol">if</span></i> <span class="paren5">(<span class="code">&gt; x y</span>)</span> 1 0</span>)</span></span>)</span></span>)</span></span>)</span> <span class="comment">; borrow</span></span></code></pre>
<p>And now the instructions themselves are trivial:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-add-reg&lt;reg <span class="paren2">(<span class="code">_ rx ry</span>)</span> <span class="comment">;; ADD Vx, Vy (8-bit)
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register rx</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">+_8 <span class="paren4">(<span class="code">register rx</span>)</span> <span class="paren4">(<span class="code">register ry</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-sub-reg&lt;reg <span class="paren2">(<span class="code">_ rx ry</span>)</span> <span class="comment">;; SUB Vx, Vy (8-bit)
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register rx</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">-_8 <span class="paren4">(<span class="code">register rx</span>)</span> <span class="paren4">(<span class="code">register ry</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This takes advantage of the fact that you can use <code>(setf (values ...) ...)</code> to
assign the multiple values returned by a function, without binding them to local
variables.</p>
<p>Notice how we just assign to <code>flag</code>. Under the hood that <code>flag</code> has been bound
with our <code>with-chip</code> macro to mean <code>(chip-flag chip)</code>, which we defined way back
in the beginning to mean <code>(aref (chip-registers chip) #xF)</code>. But isn't it much
nicer to just say <code>(setf flag ...)</code>?</p>
<p>There's also a <code>SUBN</code> instruction for subtracting the operands in reverse order
(but still storing the result in the first):</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-subn-reg&lt;reg <span class="paren2">(<span class="code">_ rx ry</span>)</span> <span class="comment">;; SUBN Vx, Vy (8-bit)
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register rx</span>)</span> flag</span>)</span>
<span class="comment">;; subtraction order is swapped for SUBN
</span> <span class="paren3">(<span class="code">-_8 <span class="paren4">(<span class="code">register ry</span>)</span> <span class="paren4">(<span class="code">register rx</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Next is an <code>ADD</code> instruction that takes an immediate value. Unlike the other
instructions this one does <em>not</em> set the flag for some reason (that was a fun
bug to track down):</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-add-reg&lt;imm <span class="paren2">(<span class="code">_ r <span class="paren3">(<span class="code">immediate 2</span>)</span></span>)</span> <span class="comment">;; ADD Vx, Imm
</span> <span class="comment">;; For some weird reason the ADD immediate op doesn't set the flag
</span> <span class="paren2">(<span class="code">zapf <span class="paren3">(<span class="code">register r</span>)</span> <span class="paren3">(<span class="code">+_8 % immediate</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Because Common Lisp will just ignore extra return values if we don't use them,
we can just use our <code>+_8</code> helper function here too and ignore the carry result.</p>
<p>There's also a single 16-bit <code>ADD</code> instruction that adds the value in
a particular register to the index register. It too ignores the <code>flag</code>:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-add-index&lt;reg <span class="paren2">(<span class="code">_ r</span>)</span> <span class="comment">;; ADD I, Vx (16-bit)
</span> <span class="paren2">(<span class="code">zapf index <span class="paren3">(<span class="code">chop 16 <span class="paren4">(<span class="code">+ % <span class="paren5">(<span class="code">register r</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<h3 id="s22-shifting"><a href="index.html#s22-shifting">Shifting</a></h3>
<p>The CHIP-8 has two bit-shifting instructions: <code>SHR</code> and <code>SHL</code> which shift
a register's contents right or left by a single bit. Both of these instructions
also set the flag to the bit that got shifted &quot;off the end&quot; of the register.</p>
<p>We'll define two more helpers to do the actual 8-bit shifting and keep track of
the bit that falls off the end:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> get-bit <span class="paren2">(<span class="code">position integer</span>)</span>
<span class="paren2">(<span class="code">ldb <span class="paren3">(<span class="code">byte 1 position</span>)</span> integer</span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> &gt;&gt;_8 <span class="paren2">(<span class="code">v</span>)</span>
<span class="paren2">(<span class="code">values <span class="paren3">(<span class="code">ash v -1</span>)</span>
<span class="paren3">(<span class="code">get-bit 0 v</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> &lt;&lt;_8 <span class="paren2">(<span class="code">v</span>)</span>
<span class="paren2">(<span class="code">values <span class="paren3">(<span class="code">chop 8 <span class="paren4">(<span class="code">ash v 1</span>)</span></span>)</span>
<span class="paren3">(<span class="code">get-bit 7 v</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>The instructions themselves are trivial:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-shr <span class="paren2">(<span class="code">_ r</span>)</span> <span class="comment">;; SHR
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register r</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">&gt;&gt;_8 <span class="paren4">(<span class="code">register r</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-shl <span class="paren2">(<span class="code">_ r</span>)</span> <span class="comment">;; SHL
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register r</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">&lt;&lt;_8 <span class="paren4">(<span class="code">register r</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p><strong>Update:</strong> as <a href="https://news.ycombinator.com/item?id=13217352">fernly pointed out</a>, this <a href="https://groups.yahoo.com/neo/groups/rcacosmac/conversations/topics/328">may not have been the
original intended behavior</a>. If we want to make our emulator match
the original intent, it's pretty simple:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-shr <span class="paren2">(<span class="code">_ rx ry</span>)</span> <span class="comment">;; SHR
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register ry</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">&gt;&gt;_8 <span class="paren4">(<span class="code">register rx</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-shl <span class="paren2">(<span class="code">_ rx ry</span>)</span> <span class="comment">;; SHL
</span> <span class="paren2">(<span class="code">setf <span class="paren3">(<span class="code">values <span class="paren4">(<span class="code">register ry</span>)</span> flag</span>)</span>
<span class="paren3">(<span class="code">&lt;&lt;_8 <span class="paren4">(<span class="code">register rx</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>But I suspect that this will probably break some ROMs that rely on the
incorrectly-documented behavior.</p>
<h3 id="s23-logical-operations"><a href="index.html#s23-logical-operations">Logical Operations</a></h3>
<p>Next up are the logical <code>AND</code>/<code>OR</code>/<code>XOR</code> instructions. We could define these
like so:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-and <span class="paren2">(<span class="code">_ destination source _</span>)</span>
<span class="paren2">(<span class="code">zapf <span class="paren3">(<span class="code">register destination</span>)</span> <span class="paren3">(<span class="code">logand % <span class="paren4">(<span class="code">register source</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-or <span class="paren2">(<span class="code">_ destination source _</span>)</span>
<span class="paren2">(<span class="code">zapf <span class="paren3">(<span class="code">register destination</span>)</span> <span class="paren3">(<span class="code">logior % <span class="paren4">(<span class="code">register source</span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-xor <span class="paren2">(<span class="code">_ destination source _</span>)</span>
<span class="paren2">(<span class="code">zapf <span class="paren3">(<span class="code">register destination</span>)</span> <span class="paren3">(<span class="code">logxor % <span class="paren4">(<span class="code">register source</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This works, but aside from the name and the operation they're all identical.
The next few groups of instructions are also going to be similar, so let's step
back for a moment and see if we can abstract away the tedium.</p>
<h3 id="s24-macro-map"><a href="index.html#s24-macro-map">Macro-Map</a></h3>
<p>Instead of typing the same thing over and over, we'd like to just say what we
want once. The traditional way to do this is with <code>macrolet</code>:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">macrolet</span></i>
<span class="paren2">(<span class="code"><span class="paren3">(<span class="code"><i><span class="symbol">define-logical-instruction</span></i> <span class="paren4">(<span class="code">name <i><span class="symbol">function</span></i></span>)</span>
`<span class="paren4">(<span class="code"><i><span class="symbol">define-instruction</span></i> ,name <span class="paren5">(<span class="code">_ destination source _</span>)</span>
<span class="paren5">(<span class="code">zapf <span class="paren6">(<span class="code">register destination</span>)</span>
<span class="paren6">(<span class="code">,<i><span class="symbol">function</span></i> % <span class="paren1">(<span class="code">register source</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">define-logical-instruction</span></i> op-and logand</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">define-logical-instruction</span></i> op-or logior</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">define-logical-instruction</span></i> op-xor logxor</span>)</span></span>)</span></span></code></pre>
<p>Now we're only writing out the actual functionality once instead of three times.
That's better, but I'm still not satisfied. Using <code>macrolet</code> means I need to
think of a name for the macro that I'm just going to use within this block and
throw away, and naming things is hard.</p>
<p>What I <em>really</em> want to do here is just &quot;map&quot; a macro over a bunch of arguments
and be done with it. I've played around a bit and ended up with a macro called
<code>macro-map</code> that does just that:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defmacro</span></i> macro-map <span class="paren2">(<span class="code">lambda-list items &amp;rest body</span>)</span>
<span class="paren2">(<span class="code"><i><span class="symbol">with-gensyms</span></i> <span class="paren3">(<span class="code">macro</span>)</span>
`<span class="paren3">(<span class="code"><i><span class="symbol">macrolet</span></i> <span class="paren4">(<span class="code"><span class="paren5">(<span class="code">,macro ,<span class="paren6">(<span class="code">ensure-list lambda-list</span>)</span> ,@body</span>)</span></span>)</span>
,@<span class="paren4">(<span class="code">iterate <span class="paren5">(<span class="code">for item <span class="keyword">:in</span> items</span>)</span>
<span class="paren5">(<span class="code">collect `<span class="paren6">(<span class="code">,macro ,@<span class="paren1">(<span class="code">ensure-list item</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p><code>macro-map</code> takes a lambda list, list of arguments, and a body for the macro and
builds the <code>macrolet</code> we wrote by hand earlier using a <code>gensym</code> for the name so
we don't have to waste brain cells thinking of one. Now we can define our
logical operations all at once:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">macro-map <span class="comment">;; AND/OR/XOR
</span> <span class="paren2">(<span class="code">NAME OP</span>)</span>
<span class="paren2">(<span class="code"><span class="paren3">(<span class="code">op-and logand</span>)</span>
<span class="paren3">(<span class="code">op-or logior</span>)</span>
<span class="paren3">(<span class="code">op-xor logxor</span>)</span></span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">define-instruction</span></i> ,name <span class="paren3">(<span class="code">_ destination source _</span>)</span>
<span class="paren3">(<span class="code">zapf <span class="paren4">(<span class="code">register destination</span>)</span> <span class="paren4">(<span class="code">,op % <span class="paren5">(<span class="code">register source</span>)</span></span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>This actually ends up being one line of code longer than the copy/pasted version
because I like to linebreak liberally, but the important thing is that we only
say each thing we need to say once.</p>
<p>Notice how this almost starts to look like a table of data rather than code.
I've taken advantage of the fact that the Lisp reader reads everything as
uppercase by default and uppercased the &quot;header&quot; row (the lambda list) to make
it stand out a bit more.</p>
<p>If you squint a little bit you might imagine how defining a set of related
instructions could almost look like <a href="https://i.imgur.com/8jbXmVj.png">a page from a CPU
manual</a>.</p>
<h3 id="s25-branching"><a href="index.html#s25-branching">Branching</a></h3>
<p>Now that we've got a way to define batches of similar instructions without going
crazy we can tackle the branching instructions.</p>
<p>Most CPUs have some form of &quot;jump to some location if zero, otherwise continue&quot;
instruction to implement branching. The CHIP-8 needs to fit every instruction
into two bytes, so it does something a bit simpler. Instead of an arbitrary
jump on a condition, it has a series of <em>skip</em> instructions.</p>
<p>For example, <code>SE Vx, 0</code> means &quot;skip the next instruction if register X is zero&quot;.
Skipping the next instruction is a simple as incrementing the program counter by
an extra two bytes.</p>
<p>There are four variants of this instruction:</p>
<pre><code>SE Vx, Immediate → Skip when Vx equals Immediate
SNE Vx, Immediate → Skip when Vx does not equal Immediate
SE Vx, Vy → Skip when Vx equals Vy
SNE Vx, Vy → Skip when Vx does not equal Vy
</code></pre>
<p>Let's use <code>macro-map</code> to write this out as a table of code:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">macro-map <span class="comment">;; SE/SNE
</span> <span class="paren2">(<span class="code"><span class="paren3">(<span class="code">NAME TEST X-ARG X-FORM Y-ARG Y-FORM</span>)</span>
<span class="paren3">(<span class="code"><span class="paren4">(<span class="code">op-se-reg-imm = <span class="paren5">(<span class="code">r 1</span>)</span> <span class="paren5">(<span class="code">register r</span>)</span> <span class="paren5">(<span class="code">immediate 2</span>)</span> immediate</span>)</span>
<span class="paren4">(<span class="code">op-sne-reg-imm not= <span class="paren5">(<span class="code">r 1</span>)</span> <span class="paren5">(<span class="code">register r</span>)</span> <span class="paren5">(<span class="code">immediate 2</span>)</span> immediate</span>)</span>
<span class="paren4">(<span class="code">op-se-reg-reg = <span class="paren5">(<span class="code">rx 1</span>)</span> <span class="paren5">(<span class="code">register rx</span>)</span> <span class="paren5">(<span class="code">ry 1</span>)</span> <span class="paren5">(<span class="code">register ry</span>)</span></span>)</span>
<span class="paren4">(<span class="code">op-sne-reg-reg not= <span class="paren5">(<span class="code">rx 1</span>)</span> <span class="paren5">(<span class="code">register rx</span>)</span> <span class="paren5">(<span class="code">ry 1</span>)</span> <span class="paren5">(<span class="code">register ry</span>)</span></span>)</span></span>)</span></span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">define-instruction</span></i> ,name <span class="paren3">(<span class="code">_ ,x-arg ,y-arg</span>)</span>
<span class="paren3">(<span class="code">when <span class="paren4">(<span class="code">,test ,x-form ,y-form</span>)</span>
<span class="paren4">(<span class="code">incf program-counter 2</span>)</span></span>)</span></span>)</span></span>)</span></span></code></pre>
<p>After the macroexpansion we end up with things like:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-sne-reg-imm <span class="paren2">(<span class="code">_ <span class="paren3">(<span class="code">r 1</span>)</span> <span class="paren3">(<span class="code">immediate 2</span>)</span></span>)</span>
<span class="paren2">(<span class="code">when <span class="paren3">(<span class="code">not= <span class="paren4">(<span class="code">register r</span>)</span> immediate</span>)</span>
<span class="paren3">(<span class="code">incf program-counter 2</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>We'll also need <code>not=</code> itself to avoid having to do messy things inside the
macro body:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">defun-inline</span></i> not= <span class="paren2">(<span class="code">x y</span>)</span>
<span class="paren2">(<span class="code">not <span class="paren3">(<span class="code">= x y</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>Just one more group of instructions left (for this post).</p>
<h3 id="s26-loads"><a href="index.html#s26-loads">Loads</a></h3>
<p>The final group of instructions we'll look at for now is the <code>LD</code> family of
loads. Normally we'd implement these first, but I wanted to introduce
<code>macro-map</code> as gently as possible.</p>
<p>Most of the <code>LD</code> instructions simply take a value from a source and stick it
into a destination, and we can implement them as a single <code>setf</code> form:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code">macro-map <span class="comment">;; LD
</span> <span class="paren2">(<span class="code">NAME ARGLIST DESTINATION SOURCE</span>)</span>
<span class="paren2">(<span class="code"><span class="paren3">(<span class="code">op-ld-i&lt;imm <span class="paren4">(<span class="code">_ <span class="paren5">(<span class="code">value 3</span>)</span></span>)</span> index value</span>)</span>
<span class="paren3">(<span class="code">op-ld-reg&lt;imm <span class="paren4">(<span class="code">_ r <span class="paren5">(<span class="code">value 2</span>)</span></span>)</span> <span class="paren4">(<span class="code">register r</span>)</span> value</span>)</span>
<span class="paren3">(<span class="code">op-ld-reg&lt;reg <span class="paren4">(<span class="code">_ rx ry _</span>)</span> <span class="paren4">(<span class="code">register rx</span>)</span> <span class="paren4">(<span class="code">register ry</span>)</span></span>)</span>
<span class="paren3">(<span class="code">op-ld-reg&lt;dt <span class="paren4">(<span class="code">_ r _ _</span>)</span> <span class="paren4">(<span class="code">register r</span>)</span> delay-timer</span>)</span>
<span class="paren3">(<span class="code">op-ld-dt&lt;reg <span class="paren4">(<span class="code">_ r _ _</span>)</span> delay-timer <span class="paren4">(<span class="code">register r</span>)</span></span>)</span>
<span class="paren3">(<span class="code">op-ld-st&lt;reg <span class="paren4">(<span class="code">_ r _ _</span>)</span> sound-timer <span class="paren4">(<span class="code">register r</span>)</span></span>)</span></span>)</span>
`<span class="paren2">(<span class="code"><i><span class="symbol">define-instruction</span></i> ,name ,arglist
<span class="paren3">(<span class="code">setf ,destination ,source</span>)</span></span>)</span></span>)</span></span></code></pre>
<p>We haven't talked about the timers yet, so don't worry about them. I'm leaving
them in so you can see how nice the <code>macro-map</code> is when you need to define lots
of similar operations at once.</p>
<p>There are two other more interesting <code>LD</code> instructions which move data between
multiple registers and memory.</p>
<p><code>LD [I], n</code> loads consecutive bytes of memory with the contents of registers
<code>V0</code> through <code>Vn</code>, starting at wherever the index register is pointing. For
example, <code>LD [I], 2</code> would be:</p>
<pre class="lineart">
V0 V1 V2 V3 V4 ...
┌──┐ ┌──┐ ┌──┐ ┌──┐ ┌──┐
│ │ │ │ │ │ │ │ │ │ ...
└─┬┘ └─┬┘ └─┬┘ └──┘ └──┘
└───┐└──┐ └─┐
│ │ │
▼ ▼ ▼
┌───┬───┬───┬───┬───┐
│ │ │ │ │ │ Memory
└───┴───┴───┴───┴───┘
▲ ┌───┐
└──│...│ Index Register
└───┘
</pre>
<p><code>LD n, [I]</code> does the opposite: it loads the contents of memory into the
registers <code>V0</code> through <code>Vn</code>.</p>
<p>Because we've used Lisp arrays for both the registers and memory, these
instructions are really lovely to implement — they end up being just a single
call to <code>replace</code>:</p>
<pre><code><span class="code"><span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-ld-mem&lt;regs <span class="paren2">(<span class="code">_ n _ _</span>)</span> <span class="comment">;; LD [I] &lt; Vn
</span> <span class="paren2">(<span class="code">replace memory registers <span class="keyword">:start1</span> index <span class="keyword">:end2</span> <span class="paren3">(<span class="code">1+ n</span>)</span></span>)</span></span>)</span>
<span class="paren1">(<span class="code"><i><span class="symbol">define-instruction</span></i> op-ld-regs&lt;mem <span class="paren2">(<span class="code">_ n _ _</span>)</span> <span class="comment">;; LD Vn &lt; [I]
</span> <span class="paren2">(<span class="code">replace registers memory <span class="keyword">:end1</span> <span class="paren3">(<span class="code">1+ n</span>)</span> <span class="keyword">:start2</span> index</span>)</span></span>)</span></span></code></pre>
<p>That's it for the <code>LD</code> instructions (for now) and for the instructions in
general!</p>
<h2 id="s27-future"><a href="index.html#s27-future">Future</a></h2>
<p>With these instructions implemented (and with some stubs for the rest) we can
load and run a ROM and it will push bytes around in memory and mostly work. In
the next few posts we'll look at the next steps to getting a fully-functional
emulator up and running, including:</p>
<ul>
<li>Graphics and input</li>
<li>Sound</li>
<li>Debugging</li>
</ul>
<p><em>Thanks to <a href="https://twitter.com/jamesnvc">James Cash</a> for reading a draft of
this post.</em></p>
</article></main><hr class='main-separator' /><footer><nav><a href='https://github.com/sjl/'>GitHub</a><a href='https://twitter.com/stevelosh/'>Twitter</a><a href='https://instagram.com/thirtytwobirds/'>Instagram</a><a href='https://hg.stevelosh.com/.plan/'>.plan</a></nav></footer></body></html>