<feed xmlns="http://www.w3.org/2005/Atom">
  <link href="https://imrannazar.com/rss.xml" rel="self" type="application/rss+xml" />
  <title type="html">Imran Nazar</title>
  <link href="https://imrannazar.com/" rel="alternate" type="text/html" />
  <subtitle>Articles on emulation and software development, with the occasional bit of sci-fi thrown in.</subtitle>
  <author><name>Imran Nazar</name><email>contact@imrannazar.com</email></author>
<entry>
 <title type="html">Pong Wars on the Commodore 64</title>
 <link href="https://imrannazar.com/articles/c64-pongwars" rel="alternate" type="text/html" title="Pong Wars on the Commodore 64" />
 <id>https://imrannazar.com/articles/c64-pongwars</id>
 <summary>A couple of years ago, I saw a graphics demo in JavaScript that I just had to recreate on the C64. Having never written a real C64 program before, it&#039;s been quite a journey, and it&#039;s all documented here.</summary>
 <category term="Articles" />
 <published>Wed, 15 Jul 2026 12:58:35 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>This post was first promised in early 2024<cite><sup>[0]</sup><mark><a href="https://hachyderm.io/@Two9A/111974181833797753" target="_blank" rel="nofollower">Pongwars on the C64</a>, @Two9A, Feb 22nd 2024</mark></cite>, but it got so long, I added a table of contents. That might be a first...</em></p>
<p>
 <ul>
  <li>
   <a href="#_top">Introduction</a>
   <ul>
    <li><a href="#_init">Before we get started</a></li>
    <li><a href="#_d64"><em>Digression</em>: Building a C64 disk image</a></li>
   </ul>
  </li>
  <li>
   <a href="#_movement">The game loop: Movement calculations</a>
   <ul>
    <li><a href="#_compl"><em>Digression the second</em>: Representing negative numbers</a></li>
    <li><a href="#_sprpos">After movement comes positioning</a></li>
    <li><a href="#_rand">An element of chance</a></li>
   </ul>
  </li>
  <li><a href="#_field">The playing field</a></li>
  <li>
   <a href="#_score">Keeping score</a>
   <ul>
    <li><a href="#_div"><em>Digression the third</em>: Binary long division</a></li>
    <li><a href="#_rscore">Rendering the score</a></li>
   </ul>
  </li>
  <li><a href="#_future">Future considerations</a></li>
  <li><a href="#_cites">Footnotes and citations</a></li>
 </ul>
</p>
<p id="_top">One day early in 2024, I was idly flipping through Mastodon when I came across this toot by Koen van Gilst<cite><sup>[1]</sup><mark><a href="https://hachyderm.io/@vnglst/111828811496422610" target="_blank" rel="nofollower">Pongwars recreated in JavaScript</a>, @vnglst, Jan 2024</mark></cite>:</p>
<figure>
 <video controls loop muted preload="auto" aria-label="@vnglst@hachyderm.io, 27th Jan 2024: I saw this online somewhere and I just had to recreate it. This is my coding happy place.">
  <source type="video/mp4" src="/content/img/c64-pongwars-vnglst.mp4">
 </video>
 <figcaption>Figure 1: The toot by @vnglst that sparked the descent into madness currently under discussion</figcaption>
</figure>
<p>This is a depiction of an eternal battle between the "day" ball and the "night" ball, to reverse the colour of the opposite ball's field. Many were transfixed, judging by the thousands of faves; I was one of them, and the thought arose unbidden:</p>
<blockquote>If van Gilst saw this online and had to recreate it in JavaScript, and now I've seen it online, I have to recreate it on the Commodore 64, right?</blockquote>
<h2>Is such a thing even possible?</h2>
<p><em>"Yes it is!"</em> Well, it seems like it should be. This is a relatively simple animation, with a random element thrown in at the point the balls contact a surface that makes them bounce; defining "a surface that makes them bounce" seems like the tricky part.</p>
<p>So we need to do some planning. And as the first step, there's some defining:</p>
<ul>
 <li>We have the <strong>ball</strong> (two of them) which moves smoothly in straight lines;</li>
 <li>There's a <strong>blockfield</strong>: the 20x20 block area over which the balls travel;</li>
 <li>The blockfield has a <strong>boundary</strong> outside of which the balls can't travel, and they bounce off the boundary;</li>
 <li>And there are two <strong>sides</strong> whose edges also cause the ball to bounce, but the block that gets hit reverses sides.</li>
</ul>
<p>This is all complicated by the fact that, despite a lifelong interest in hacking at the C64, I'd never to this point written anything substantial in assembly for the machine. Looks like we'll be learning as we go.</p>
<p>On most machines of the era video was output to a CRT, as explained in my megathread on the 1541 disk drive from a couple of years back<cite><sup>[2]</sup><mark><a href="https://imrannazar.com/articles/commodore-1541" target="_blank" rel="nofollower">"Why Was the Commodore 64 Disk Drive So Slow?"</a>, Imran Nazar, Dec 2024</mark></cite>. After each frame of video output comes a short vertical blanking period, during which the video chip is not making any demands on memory; we'll be looking to try to limit any calculations needed for this animation, so they're completed within the blanking period and we're not unduly affecting other things that may be happening on the machine during the frame rendering period.</p>
<p>On the Commodore 64, the BASIC interpreter is the main thing that might be running during that period, and it provides some helpful things for this effect. One of those is a hook that gets triggered at the bottom of every frame<cite><sup>[3]</sup><mark><a href="https://www.c64-wiki.com/wiki/Raster_interrupt" target="_blank" rel="nofollower">"Raster interrupt"</a>, C64 Wiki, updated Mar 2024</mark></cite>, allowing custom code to be called every frame while keeping BASIC running. So we can plan out something like this for the code:</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-mainloop.png" alt="The main loop: initialisation, then for each frame: calculation of the ball's next position and/or bounces, calculation of the score, rendering of the field/balls/score">
 <figcaption>Figure 2: Flow chart for the main loop</figcaption>
</figure>
<h2 id="_init">Before we get started</h2>
<p>So let's look at the initialisation portion: we'll be keeping an internal representation of the state of the blockfield, but there's also the on-screen blockfield to set up. The C64 has a 40x25 area of characters in its default text mode (each character being an 8x8 pixel square), and there are two areas of memory of interest here:</p>
<ul>
 <li>The <strong>screen RAM</strong> sits at <code>$0400</code> by default, and is a thousand-byte area where the character values are stored;</li>
 <li>The <strong>color RAM</strong> at <code>$D800</code> is a thousand nybbles<cite><sup>[A]</sup><mark>A nybble is four bits, as opposed to an 8-bit byte.</mark></cite> where each location can represent one of the C64's 16 colours.</li>
</ul>
<p>Immediately after screen RAM sit the pointers to sprite data, but we're not setting up any sprites (yet), so a little shortcut is to write 1024 bytes to screen. This writes past the end of the screen, but makes the code much simpler:</p>
<samp>
 <pre>SCRRAM = <var>$0400</var>
BLOCKPTR = <var>$03</var>   <s>; A block of two bytes not used by BASIC</s>

<var>init</var>:
    <kbd>subroutine</kbd>

    <s>; Set up a pointer to screen RAM, starting at the top left</s>
    <s>; The 65xx CPUs are little-endian, so low byte first</s>
    <kbd>lda</kbd> #&lt;SCRRAM
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> #&gt;SCRRAM
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; We'll be writing SPACE (character 32), not char 0 which is @</s>
    <kbd>lda</kbd> #<var>32</var>

    <s>; Four lots of 256, for 1024 writes</s>
    <kbd>ldx</kbd> #<var>4</var>
    <kbd>ldy</kbd> #<var>0</var>

<var>.blank</var>:
    <s>; The inner loop: runs from Y=0 through 255, 254, ...0 again</s>
    <kbd>sta</kbd> (BLOCKPTR), y
    <kbd>dey</kbd>
    <kbd>bne</kbd> <var>.blank</var>

    <s>; The outer loop: punt the pointer along by 256 each go-around</s>
    <kbd>inc</kbd> <var>BLOCKPTR</var> + <var>1</var>
    <kbd>dex</kbd>
    <kbd>bne</kbd> <var>.blank</var></pre>
</samp>
<p>(As an aside, <code>BLOCKPTR</code> is set to a value which is "not used by BASIC", but how do we know that? It turns out there's a detailed map of memory used by the C64, by Joe Forster of the STA demo group<cite><sup>[4]</sup><mark><a href="https://sta.c64.org/cbm64mem.html" target="_blank" rel="nofollower">Commodore 64 memory map</a>, STA, last updated probably a while ago as the page is HTML 4.01</mark></cite>, which states locations that the BASIC and Kernal ROMs don't touch in their standard operation, and which are free for programs to use.)</p>
<p>With the screen a uniformly blank Commodore blue, we can draw out the blockfield as a 20x20 area. The display of the C64 allows each character to have a foreground colour in text mode, but the background colour is shared across the whole screen; if we want to use colour RAM to indicate which blocks are white and which are black (and we do), we'll want a character that's all foreground colour with no holes.</p>
<figure>
 <img src="/content/img/c64-pongwars-charset.png" alt="Character set of the C64, in two blocks of 128">
 <figcaption>Figure 3: C64 Character set 1, in two sets of 128<br>Source: Jodigi, admin of the C64 Wiki<cite><sup>[5]</sup><mark><a href="https://www.c64-wiki.com/wiki/Character_set" target="_blank" rel="nofollower">"Character set"</a>, C64 Wiki, updated Aug 2025</mark></cite></figcaption>
</figure>
<p>As the second half of the character set contains reverse-video copies of the first half, we can use the reverse-video version of SPACE (character 160) as our fully-foreground block. Our loop is a little more complicated: to write rows of 20 characters on a screen that's 40 wide, we need to write 20 and skip 20; additionally, we'll want to put this block centrally on the screen, so we need to start one row down and 10 characters in.</p>
<p>Our resultant pointer is actually one row and <em>nine</em> characters after the start of screen RAM, because we can achieve the effect of writing 20 bytes in a row either by starting at 0 and going up to 19 (aborting at 20), or starting at 20 and coming down to 1 (aborting at 0). The latter saves us a compare, so is both quicker and smaller in code size.</p>
<samp>
 <pre>    <kbd>lda</kbd> #&lt;(SCRRAM + <var>40</var> + <var>9</var>)
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> #&gt;(SCRRAM + <var>40</var> + <var>9</var>)
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; This time we're writing 20 rows of 20, char 160</s>
    <s>; We'd normally think of this as X being along the line, and Y down</s>
    <s>; but the 65xx only offers indirect addressing with Y as the index</s>
    <kbd>ldx</kbd> #<var>20</var>

<var>.field</var>:
    <kbd>lda</kbd> #<var>160</var>
    <kbd>ldy</kbd> #<var>20</var>
<var>.row</var>:
    <kbd>sta</kbd> (BLOCKPTR), y
    <kbd>dey</kbd>
    <kbd>bne</kbd> <var>.row</var>

    <s>; Add 40 to the BLOCKPTR (16-bit add)</s>
    <s>; Clobbers A, will need reloading at the top of the .field loop</s>
    <kbd>lda</kbd> BLOCKPTR
    <kbd>adc</kbd> #<var>40</var>
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> BLOCKPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <kbd>dex</kbd>
    <kbd>bne</kbd> <var>.field</var></pre>
</samp>
<p>With the screen RAM fully set up, next comes the colour RAM. As it turns out (peeking ahead) we'll be using a double-buffering technique to simplify the bounce calculations: that means an internal buffer of 400 contiguous black-or-white values for the blockfield, which is rendered to colour RAM each frame. So our initialisation becomes setup of the internal blockfield buffer:</p>
<samp>
 <pre>BLOCKBUF = <var>$CE00</var>   <s>; 512 bytes unused RAM, which is ample</s>

    <kbd>lda</kbd> #&lt;BLOCKBUF
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> #&gt;BLOCKBUF
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; The initial blockfield is half black (colour 0), half white (1)</s>
    <s>; In other words, 20 rows of 10 black and 10 white</s>
    <s>; In other other words, 40 areas of alternating black and white</s>
    <kbd>lda</kbd> #<var>0</var>
    <kbd>ldx</kbd> #<var>40</var>
<var>.fill</var>:

    <s>; The inner loop, writing the area of 10 (either black or white)</s>
    <s>; This time, write from 9 to 0 inclusive, and stop at -1</s>
    <kbd>ldy</kbd> #<var>9</var>
<var>.fill_row</var>:
    <kbd>sta</kbd> (BLOCKPTR), y
    <kbd>dey</kbd>
    <kbd>bpl</kbd> <var>.fill_row</var>

    <s>; Add 10 to BLOCKPTR (16-bit add)</s>
    <s>; Clobbers A, but this time we can't just write a fixed value afresh</s>
    <s>; So push A to the stack</s>
    <kbd>pha</kbd>
    <kbd>lda</kbd> BLOCKPTR
    <kbd>adc</kbd> #<var>10</var>
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> BLOCKPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; Pull A back off the stack, and XOR 1 to swap between 0 and 1</s>
    <kbd>pla</kbd>
    <kbd>eor</kbd> #<var>1</var>

    <kbd>dex</kbd>
    <kbd>bne</kbd> <var>.fill</var></pre>
</samp>
<p>And we're almost done with the initialisation steps. There are two things left to do: set up the sprites for our smoothly-moving balls, and connect the hook for our main routine. So we'll need to design an 8x8-pixel representation of a ball; it turns out that the Minecraft scene has a plethora of pixelated shape generators online, so we can use a circle generator<cite><sup>[6]</sup><mark><a href="https://donatstudios.com/PixelCircleGenerator" target="_blank" rel="nofollower">"Pixel Circle Generator"</a>, Donat Studios, updated Jul 2025</mark></cite> set to 8x8:</p>
<figure>
 <img src="/content/img/c64-pongwars-circle.png" alt="Pixel Circle Generator interface, with a circle shown below">
 <figcaption>Figure 4: Pixel Circle Generator set to filled circles of width 8</figcaption>
</figure>
<p>Just like the text characters on a C64, sprites can have a foreground colour for any pixels that are set in the sprite, and a background that shines through for pixels that aren't set. That means sprites can be defined in binary; the text characters are 8x8 pixels, but sprites are 24x21, and the video chip expects binary data corresponding to that size when setting up the sprite. Our ball itself is only 8x8 pixels, so the rest will need to be padded out with 0's.</p>
<p>24x21 bits of data is 63 contiguous bytes, so the C64's video chip expects a pointer to the sprite data to be aligned to a 64-byte boundary; as a result, it actually expects the pointer <em>divided by 64</em> as a sort of "data block index" during setup of the sprite. As we mentioned earlier, the pointers to the sprite are, by default, immediately after the screen text in RAM:</p>
<samp>
 <pre>SPRPTR = SCRRAM + (<var>40</var> * <var>25</var>)

    <kbd>lda</kbd> #(ballmap / <var>64</var>)
    <kbd>sta</kbd> SPRPTR       <s>; Sprite 0</s>
    <kbd>sta</kbd> SPRPTR + <var>1</var>   <s>; Sprite 1</s>

    <s>; This will end up at the bottom of our source code,
    ; in a "data section". For now it's presented alongside</s>
    <kbd>align</kbd> <var>64</var>
<var>ballmap</var>:
    <kbd>byte</kbd> %<var>00111100</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>01111110</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>11111111</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>11111111</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>11111111</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>11111111</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>01111110</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00111100</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var>
    <kbd>byte</kbd> %<var>00000000</var>, %<var>00000000</var>, %<var>00000000</var></pre>
</samp>
<p>With the sprite data set up, we can inform the video chip of the colours we'd like for each sprite's foreground, and then turn the sprites on. We're not setting the onscreen location of the sprites here, that'll be done by the rendering code; their default position of 0x0 is off the screen to the top left, which is usefully out of the way.</p>
<p>On the C64, talking to the hardware is done in the same way as talking to memory: writing to and/or reading from special addresses. In the documentation, these are referred to as "registers" for the various chips; the video interface chip (VIC) has over 40 of these, but for our purposes we're interested in those that control sprites 0 and 1.</p>
<figure>
 <table>
  <thead>
   <tr><th>Sprite</th><th>Location</th><th>Name</th><th>Detail</th></tr>
  </thead>
  <tbody>
   <tr><td rowspan="3">0</td><td><code>$D000</code></td><td>SPR0X</td><td>X-position</td></tr>
   <tr><td><code>$D001</code></td><td>SPR0Y</td><td>Y-position</td></tr>
   <tr><td><code>$D027</code></td><td>SPR0COL</td><td>Colour</td></tr>
   <tr><td rowspan="3">1</td><td><code>$D002</code></td><td>SPR1X</td><td>X-position</td></tr>
   <tr><td><code>$D003</code></td><td>SPR1Y</td><td>Y-position</td></tr>
   <tr><td><code>$D028</code></td><td>SPR1COL</td><td>Colour</td></tr>
   <tr><td rowspan="2">All</td><td><code>$D010</code></td><td>SPRXHI</td><td>X-position, 9th bit<br>One bit for each sprite</td></tr>
   <tr><td><code>$D015</code></td><td>SPREN</td><td>Sprite enable<br>One bit for each sprite</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: VIC sprite control registers for sprites 0 and 1</figcaption>
</figure>
<p>There's an interesting wrinkle here that we'll look at in more detail when it comes to rendering the sprites, because the screen is more than 256 pixels across, which means the X-coordinate doesn't fit in one byte; instead, there's a bit in <code>SPRXHI</code> for each sprite that one needs to set when it's over on the right side of the screen. For now, we'll put that aside:</p>
<samp>
 <pre><s>    ; Sprite 0 starts on the black side, and is white</s>
    <kbd>lda</kbd> #<var>1</var>
    <kbd>sta</kbd> SPR0COL

    <s>; Sprite 1 starts on the white side, and is black</s>
    <kbd>lda</kbd> #<var>0</var>
    <kbd>sta</kbd> SPR1COL

    <kbd>lda</kbd> #%<var>00000011</var>
    <kbd>sta</kbd> SPREN</pre>
</samp>
<p>And we're done setting things up: the blockfield is in place, the sprites are enabled, and the only thing left is to tell the C64 where to look for the rendering code that runs every frame.</p>
<samp>
 <pre>IRQ = <var>$0314</var>

    <s>; Disable interrupts, so we don't
    ; get ...interrupted during setup</s>
    <kbd>sei</kbd>

    <kbd>lda</kbd> #&lt;isr
    <kbd>sta</kbd> IRQ
    <kbd>lda</kbd> #&gt;isr
    <kbd>sta</kbd> IRQ + <var>1</var>

    <kbd>cli</kbd>

<s>; Interrupt service routine: main renderer</s>
<var>isr</var>:
    <kbd>subroutine</kbd>

    <s>; ISRs need to run transparently, without clobbering
    ; any registers, so we save the full state to stack</s>
    <kbd>pha
    txa
    pha
    tya
    pha</kbd>

    <s>; TODO: The rendering here</s>
    <kbd>jsr</kbd> advance_white
    <kbd>jsr</kbd> collide_white
    <kbd>jsr</kbd> advance_black
    <kbd>jsr</kbd> collide_black
    <kbd>jsr</kbd> render_field
    <kbd>jsr</kbd> render_score

    <s>; And pull the state back off the stack, in reverse order</s>
    <kbd>pla
    tay
    pla
    tax
    pla</kbd>

    <s>; Return to where the C64 would normally
    ; go during service of this interrupt</s>
    <kbd>jmp</kbd> $<var>EA31</var></pre>
</samp>
<p>We have ourselves a full program here, though it doesn't do a great deal yet. If we assemble this and build a disk image to load into an emulator<cite><sup>[B]</sup><mark>I'm using <a href="https://vice-emu.sourceforge.io/" target="_blank" rel="noreferrer">VICE</a> here, which is perhaps the most accurate emulator of anything ever built.</mark></cite> we might get something like this.</p>
<figure>
 <img src="/content/img/c64-pongwars-init.png" alt="A C64 screen with a blank 20x20 area in the centre">
 <figcaption>Figure 5: Our Pongwars implementation after initialisation</figcaption>
</figure>
<h2 id="_d64">Digression: Building a C64 disk image</h2>
<p>While hacking on this, I realised that emulators don't generally take a binary image and allow you to drop it into the C64's memory to be run. The standard user-friendly way of loading a program would be to load it from a disk (or disk image, in this case), so we'll want to take our program as written in assembly, and get it into a disk image.</p>
<p>It turns out VICE provides tools to work on disk images, as it needs to emulate the 1541 disk drive as well as the C64 in order to provide disk connectivity, and you get those tools essentially for free as part of the implementation. In this case, a command-line emulation of the disk drive is available as <code>c1541</code>, and it can be instructed to perform all the steps necessary to create a disk image:</p>
<ul>
 <li><strong>Format</strong> a disk to lay down the pattern of tracks into an image;</li>
 <li><strong>Attach</strong> the image to the emulator;</li>
 <li><strong>Write</strong> our program to disk, and put its name in the directory listing.</li>
</ul>
<samp>
 <h3><code>Makefile</code>: Assembly and image generation</h3>
 <pre><s># Change VICE_ROOT to point to your VICE binaries
# I'm on an M1 Mac, so this is the arm64/osx copy</s>
VICE_ROOT = <var>/Applications/vice-arm64-gtk3-3.7.1/bin</var>
NAME = <var>pongwars</var>

<kbd>all</kbd>: $(<var>NAME</var>).d64

<kbd>$(</kbd><var>NAME</var><kbd>).d64</kbd>: $(<var>NAME</var>).prg
    $(<var>VICE_ROOT</var>)/<kbd>c1541</kbd> \
        -<kbd>format</kbd> $(<var>NAME</var>),<var>8</var> <var>d64</var> $(<var>NAME</var>).d64 \
        -<kbd>attach</kbd> $(<var>NAME</var>).d64 \
        -<kbd>write</kbd> $(<var>NAME</var>).prg $(<var>NAME</var>)

<kbd>$(</kbd><var>NAME</var><kbd>).prg</kbd>: $(<var>NAME</var>).asm
    <kbd>dasm</kbd> $(<var>NAME</var>).asm -<kbd>o</kbd>$(<var>NAME</var>).prg</pre>
</samp>
<p>(It also bears mentioning that I'm using dASM<cite><sup>[7]</sup><mark><a href="https://github.com/dasm-assembler/dasm/" target="_blank" rel="noreferrer">dASM assembler</a>, GitHub, last release 2020</mark></cite> to assemble the 6502 code written here into a binary image, that can then be pushed to the disk image by <code>c1541</code>.)</p>
<h2 id="_movement">The game loop: Movement calculations</h2>
<p>So we come back to the program under consideration, having set up our initialisation steps; we now have a empty game loop that needs to be filled in. From Figure 2, we know that our main steps are to advance the two balls, check for collisions, and render the updated block field and score.</p>
<p>What does it mean to "advance the ball"? Well, if we check back to Figure 1, we see that the balls start off in the middle of their fields, and they move at a fixed speed per frame, but their direction can change. If our fixed speed is one pixel per frame, trigonometry tells us that the ball needs to be moved by a <em>fractional</em> number of pixels in the horizontal and vertical directions:</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-trig.png" alt="A right-angle triangle with theta as the labelled angle, and cos/sin theta on the axial legs">
 <figcaption>Figure 6: Components of a unit vector</figcaption>
</figure>
<p>We can't actually move the sprites by a fractional number of pixels, but we can keep track of the fractions and move the sprites if the calculation bumps their position across to the next whole number. If, for example, &theta; was 35 degrees our ball position might look like this for consecutive frames:</p>
<figure>
 <table>
  <thead><tr><th>Frame</th><th>X-position</th><th>Y-position</th><th>Screen coords</th></tr></thead>
  <tbody>
   <tr><td>0</td><td>0</td><td>0</td><td>0, 0</td></tr>
   <tr><td>1</td><td>0.819</td><td>0.574</td><td>0, 0</td></tr>
   <tr><td>2</td><td>1.638</td><td>1.147</td><td>1, 1</td></tr>
   <tr><td>3</td><td>2.457</td><td>1.720</td><td>2, 1</td></tr>
   <tr><td>4</td><td>3.277</td><td>2.294</td><td>3, 2</td></tr>
  </tbody>
 </table>
 <figcaption>Table 2: Consecutive positions for a ball at speed 1, direction 35&deg;</figcaption>
</figure>
<p>When I talk about fractions in computing, it's probable that your mind immediately goes to floating-point numbers, which can represent most fractions you're likely to run into. The Commodore 64 does support floating-point operations, but they're astoundingly slow: without dedicated hardware to handle them, the BASIC interpreter handles floating-point numbers in text form, performing calculations internally using its own binary format and translating back to text for storage.</p>
<p>For our purposes, there is another way: <em>fixed-point</em> numbers, where the fractional and integer parts of the number are always a given length and don't change between numbers. This works for us for multiple reasons:</p>
<ul>
 <li>We know the field is 20x20 blocks, which is 160x160 pixels, so the whole-number part of the ball's coordinate (horizontal or vertical) can fit into a byte and can be taken directly from that byte to plot the ball on-screen;</li>
 <li>As per Figure 6, the direction of the ball is a unit vector, so <code>cos &theta;</code> and <code>sin &theta;</code> are always less than 1. In fact, they can be directly lifted from a lookup table for the sine function.</li>
</ul>
<p>We can further simplify things by ranging &theta; through 256 "degrees" instead of the traditional 360, allowing the direction of the ball to fit into one byte. Putting this all together, our internal representation of the ball's state would be a structure of five bytes, laid out something like this:</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-balldata.png" alt="Five-byte data structure for ball state: theta, X-coordinate, Y-coordinate">
 <figcaption>Figure 7: Data structure of the ball state</figcaption>
</figure>
<p>With our data structure comes an initialisation step, which we'll want to add to the init code from earlier. This allows us to set up the balls' initial position and direction on the block field, which we can then use in the renderer:</p>
<samp>
 <pre><s>; Ball data spans five bytes</s>
BALL0 = <var>$D9</var>
BALL1 = <var>$DE</var>

<var>init:</var>
    <s>; ...</s>
    <s>; Copy initial position data into zero-page</s>
    <s>; We can do both sets of 5 bytes consecutively</s>
    <kbd>ldx</kbd> #<var>10</var>
<var>.spr_init</var>:
    <kbd>lda</kbd> posdata, x
    <kbd>sta</kbd> BALL0, x
    <kbd>dex</kbd>
    <kbd>bpl</kbd> <var>.spr_init</var>

<var>posdata</var>:
    <s>; White ball: Theta 32 (south-east), X 40.0, Y 40.0</s>
    <kbd>byte</kbd> <var>32</var>, <var>40</var>, <var>0</var>, <var>60</var>, <var>0</var>
    <s>; Black ball: Theta 160 (north-west), X 120.0, Y 120.0</s>
    <kbd>byte</kbd> <var>160</var>, <var>120</var>, <var>0</var>, <var>120</var>, <var>0</var></pre>
</samp>
<p>And we can finally start adding pieces to our game loop. From Figure 2, we'll want to advance the balls' positions and render their new locations, as the first visible step. That'll involve adding the horizontal and vertical components of the unit vector, for which we'll want a sine/cosine lookup table</p>
<p>One thing to note about the 6510 processor in the C64 is that it has a bug in the indexed addressing mode: if you have a table of 256 values that's not aligned to a 256-byte boundary, adding the index register can cause your final location to wrap around the boundary instead of continuing through to the rest of the table. In other words, a percentage of your lookup table becomes inaccessible, because the index never reaches that portion before looping back.</p>
<p>We have to take care to align our lookup table to a page boundary, using the assembler's <code>align</code> keyword, to avoid this bug. However, we can also use this to our advantage: the cosine function is the same as the sine function with an offset of a quarter of the waveform, so we can retrieve a sine value for a particular angle by indexing into the table, and adding 64 to the index to obtain the cosine for that same angle. If adding 64 would take us off the end of the table, no problem: that wrap-around means we land back near the start, on the index we were looking for.</p>
<p>Putting all that together, we get a pair of subroutines to advance the balls' position, that look a little like the below (I'm including the routine for the black ball only here, the white ball will look substantially similar):</p>
<samp>
 <pre><var>advance_black</var>:
    <kbd>subroutine</kbd>

    <s>; x += cos(theta)</s>
    <kbd>lda</kbd> BALL0
    <kbd>clc</kbd>
    <kbd>adc</kbd> #<var>64</var>
    <kbd>tax</kbd>
    <kbd>lda</kbd> sindata, x   <s>; LUT wrap-around</s>
    <kbd>ldy</kbd> #(BALL0 + <var>1</var>)
    <kbd>jsr</kbd> add_u16_s8

    <s>; y += sin(theta)</s>
    <kbd>lda</kbd> BALL0
    <kbd>tay</kbd>
    <kbd>lda</kbd> sindata, y
    <kbd>ldy</kbd> #(BALL0 + <var>3</var>)
    <kbd>jsr</kbd> add_u16_s8

    <s>; TODO: Position on-screen</s>

    <kbd>rts</kbd>

    <s>;--------------------------------</s>
    <kbd>align</kbd> <var>256</var>
<var>sindata</var>:
    <kbd>hex</kbd> <var>00 03 06 09 0C 10 13 16 19 1C </var>
    <kbd>hex</kbd> <var>1F 22 25 28 2B 2E 31 33 36 39 </var>
    <kbd>hex</kbd> <var>3C 3F 41 44 47 49 4C 4E 51 53 </var>
    <kbd>hex</kbd> <var>55 58 5A 5C 5E 60 62 64 66 68 </var>
    <kbd>hex</kbd> <var>6A 6B 6D 6F 70 71 73 74 75 76 </var>
    <kbd>hex</kbd> <var>78 79 7A 7A 7B 7C 7D 7D 7E 7E </var>
    <kbd>hex</kbd> <var>7E 7F 7F 7F 7F 7F 7F 7F 7E 7E </var>
    <kbd>hex</kbd> <var>7E 7D 7D 7C 7B 7A 7A 79 78 76 </var>
    <kbd>hex</kbd> <var>75 74 73 71 70 6F 6D 6B 6A 68 </var>
    <kbd>hex</kbd> <var>66 64 62 60 5E 5C 5A 58 55 53 </var>
    <kbd>hex</kbd> <var>51 4E 4C 49 47 44 41 3F 3C 39 </var>
    <kbd>hex</kbd> <var>36 33 31 2E 2B 28 25 22 1F 1C </var>
    <kbd>hex</kbd> <var>19 16 13 10 0C 09 06 03 00 FD </var>
    <kbd>hex</kbd> <var>FA F7 F4 F0 ED EA E7 E4 E1 DE </var>
    <kbd>hex</kbd> <var>DB D8 D5 D2 CF CD CA C7 C4 C1 </var>
    <kbd>hex</kbd> <var>BF BC B9 B7 B4 B2 AF AD AB A8 </var>
    <kbd>hex</kbd> <var>A6 A4 A2 A0 9E 9C 9A 98 96 95 </var>
    <kbd>hex</kbd> <var>93 91 90 8F 8D 8C 8B 8A 88 87 </var>
    <kbd>hex</kbd> <var>86 86 85 84 83 83 82 82 82 81 </var>
    <kbd>hex</kbd> <var>81 81 81 81 81 81 82 82 82 83 </var>
    <kbd>hex</kbd> <var>83 84 85 86 86 87 88 8A 8B 8C </var>
    <kbd>hex</kbd> <var>8D 8F 90 91 93 95 96 98 9A 9C </var>
    <kbd>hex</kbd> <var>9E A0 A2 A4 A6 A8 AB AD AF B2 </var>
    <kbd>hex</kbd> <var>B4 B7 B9 BC BF C1 C4 C7 CA CD </var>
    <kbd>hex</kbd> <var>CF D2 D5 D8 DB DE E1 E4 E7 EA </var>
    <kbd>hex</kbd> <var>ED F0 F4 F7 FA FD</var></pre>
</samp>
<p>But wait, what's this <code>add_u16_s8</code>? Well, you'll recall that each component of the ball's position is a fixed-point number, with 8 bits either side of the point; this is equivalent to an unsigned 16-bit number. Adding a value from the sine table to this fixed-point number is thus the same as adding a signed 8-bit number (a number that can range from -128 to +127) to our 16-bit number.</p>
<p>The processor doesn't have native handling of 16-bit numbers, so we'll have to build a routine for that. Fortunately, such a routine is fairly straightforward: we add our 8-bit value to the low end (our fractional component in this case), and if the value overflows the 8-bit range it'll set the processor's <code>CARRY</code> flag. We then either add or subtract the <code>CARRY</code> from the high end (our whole component) depending on whether our 8-bit value was positive or negative.</p>
<p>The processor can help us with the "whether a number is negative" part too: one of the other flags available is <code>NEGATIVE</code>, which is the same as the top bit of an 8-bit value after calculation (the top bit being how one traditionally denotes a negative number). Alongside that come the <code>bpl</code> and <code>bmi</code> instructions, which stand for "branch if plus" and "branch if minus".</p>
<p>We can use <code>bpl</code> with an instruction that doesn't <em>change</em> the value, but does set <code>NEGATIVE</code> to allow us to take those two branches:</p>
<samp>
 <pre><s>; add_u16_s8: Add 8-bit signed to 16-bit unsigned
; @param A The 8-bit signed
; @param Y Zero-page pointer to the 16-bit unsigned
; @return Changed value in zero-page
; @clobbers A
; @preserves Y</s>
<var>add_u16_s8</var>:
    <kbd>subroutine</kbd>
    <kbd>and</kbd> #<var>255</var>      <s>; Set N</s>
    <kbd>bpl</kbd> .positive

<var>.negative</var>:
    <kbd>clc</kbd>
    <kbd>adc</kbd> <var>1</var>, y      <s>; Add fraction</s>
    <kbd>sta</kbd> <var>1</var>, y
    <kbd>lda</kbd> <var>0</var>, y
    <kbd>sbc</kbd> #<var>0</var>        <s>; Subtract C from whole</s>
    <kbd>sta</kbd> <var>0</var>, y
    <kbd>jmp</kbd> .end

<var>.positive</var>:
    <kbd>clc</kbd>
    <kbd>adc</kbd> <var>1</var>, y      <s>; Add fraction</s>
    <kbd>sta</kbd> <var>1</var>, y
    <kbd>lda</kbd> <var>0</var>, y
    <kbd>adc</kbd> #<var>0</var>        <s>; Add C to whole</s>
    <kbd>sta</kbd> <var>0</var>, y

<var>.end</var>:
    <kbd>rts</kbd></pre>
</samp>
<h2 id="_compl">Digression the second: Representing negative numbers</h2>
<p>The keen-eyed reader will have seen something weird in the above explanation of how <code>add_u16_s8</code> works:</p>
<blockquote>We add our 8-bit value to the low end (our fractional component in this case)... then either add or subtract the CARRY from the high end (our whole component)</blockquote>
<p>Surely if the number is negative we'd want to subtract both times? To look at why we don't, it's worth a quick note on the history of representing negative numbers in computing.</p>
<p>Computers were, to begin with, exclusively the domain of mathematicians and people who would be familiar with the esoteric field of binary numbers, so the number handling was built around being able to read those numbers off from the "blinkenlights" directly in binary. The simplest way to handle both positive and negative numbers was simply to mark one bit in the number as "the negative bit", and the rest of the number would represent the value; this was called "sign and magnitude" representation. For example:</p>
<samp>
 <pre>Twenty-three and negative twenty-three:
0 0010111
1 0010111</pre>
</samp>
<p>To perform a subtraction (or to add a negative number, which is functionally equivalent) while only having adding circuitry, the computer needs to perform some precalculation otherwise it'll end up with the wrong answer:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + 10010111
                 --------
                 11001100
                 negative eighty six</pre>
</samp>
<p>The sign-and-magnitude negative number needs to be inverted (or <em>one's-complemented</em> in the mathematical jargon) when performing a subtraction, so that adding it has the intended effect of reducing the value instead of piling on top:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + <var>11101000</var>
                 --------
              [1]00100111
                 thirty nine (and a carry)</pre>
</samp>
<p>Except complementing doesn't quite fix it: because sign-and-magnitude numbers can have zero (<code>00000000</code>) <em>and</em> negative zero (<code>10000000</code>), we need to add one after inverting to step over the negative zero value:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + <var>1110100</var><s>1</s>
                 --------
              [1]00101000
                 forty (and a carry)</pre>
</samp>
<p>To summarise: negative numbers were represented as a negative sign bit and the value as the magnitude, for easier reading off from binary displays, but the computer would need to first invert the number and then add one in order to perform the addition of a negative number.</p>
<p>As binary read-off displays went away with the growing ubiquity of computing, it began to make sense to simplify the representation of negative numbers not for the human mathematician using the computer, but for the computer's internal operation. The best thing for the computer, of course, would be to remove this whole pipeline of needing to complement the number and add one, before being able to add a negative number.</p>
<p>And that's how we landed at <em>two's-complement</em> (two's because we add one to the one's-complement) representation as the standard for binary negative numbers: if the sign bit is set to negative in the number, the rest of the value is <em>already</em> inverted and has one added, so the computer just needs to add the whole value as normal.</p>
<p>This does increase the cognitive load on a programmer working at a low level, because your binary numbers no longer read "normally":</p>
<samp>
 <pre>00000000 =    0
00000001 =    1
00000010 =    2
...
01111110 =  126
01111111 =  127
10000000 = -128 (not -0)
10000001 = -127 (not -1)
10000010 = -126 (not -2)
...
11111110 =   -2
11111111 =   -1</pre>
</samp>
<p>But when are we going to be working at a sufficiently low level that we have to remember about two's-complement representation in the microcomputer age of the '80s, with high-level languages such as BASIC widely available? When we need to eke out more performance than BASIC can give us, which is what we need here.</p>
<p>That's why <code>add_u16_s8</code> performs an addition on both branches, whether the <code>s8</code> is positive or negative.</p>
<h2 id="_sprpos">After movement comes positioning</h2>
<p>Back to our regularly scheduled programming, we're now able to advance the internal representation of the balls' positions, but we're not yet able to see the balls moving on-screen. For that to happen, we need to set the positions of the sprites in the video chip's registers, except we can't naively copy the calculated values over: the top-left of our playing field isn't at sprite coordinate 0,0. Heck, the top-left of the screen isn't at 0,0.</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-sprpos.png" alt="Scan from a printed page: Diagram of the C64 screen, showing six sprite positions. Position 1 is annotated '24,50'">
 <figcaption>Figure 8: Sprite positioning coordinates on the C64. I believe this is lifted from the Programmer's Reference, by way of Mike Dailly<cite><sup>[8]</sup><mark><a href="https://lemmings.info/rasters-sprites-and-multiplexing/" target="_blank" rel="noreferrer">"Raster's, Sprites and Multiplexing"</a>, Mark Dailly, Jul 2024</mark></cite></figcaption>
</figure>
<p>From some time earlier, you'll recall that our blockfield is one row and ten characters in from the top-left of the screen, which (given that each character is 8x8 pixels) is eight pixels down and 80 across. As a result, to plot the ball sprite where we want it on-screen we need to add 104 to the X coordinate, and 58 to the Y.</p>
<p>And now that wrinkle we mentioned earlier comes back around: <code>SPRXHI</code>, the video chip control register that contains the 9th bit of each sprite's X-coordinate. The VIC combines this with the lower eight bits to generate the final position, which means we need to update <code>SPRXHI</code> appropriately each time we set the balls' positions.</p>
<p><em>As an aside, the furthest right our ball can go in the playing field is 19 blocks before bouncing off the right edge, which is 152 pixels; adding our offset of 104 leaves a final position of 256. If our playing field were even one pixel left of centre, we wouldn't have to worry about <code>SPRXHI</code> during our game loop.</em></p>
<p>So let's translate this into code by filling out the rest of <code>advance_black</code>. You'll recall from Figure 7 that each ball has a data structure in memory that holds the coordinates in fixed-point number format, so we only need the whole-number portion of each coordinate when translating to on-screen position. We left a <code>TODO</code> in the code previously, so bringing that down from above:</p>
<samp>
 <pre><var>advance_black</var>:
    <kbd>subroutine</kbd>

    <s>; x += cos(theta)</s>
    <kbd>lda</kbd> BALL0
    <kbd>clc</kbd>
    <kbd>adc</kbd> #<var>64</var>
    <kbd>tax</kbd>
    <kbd>lda</kbd> sindata, x   <s>; LUT wrap-around</s>
    <kbd>ldy</kbd> #(BALL0 + <var>1</var>)
    <kbd>jsr</kbd> add_u16_s8

    <s>; y += sin(theta)</s>
    <kbd>lda</kbd> BALL0
    <kbd>tay</kbd>
    <kbd>lda</kbd> sindata, y
    <kbd>ldy</kbd> #(BALL0 + <var>3</var>)
    <kbd>jsr</kbd> add_u16_s8

    <s>; Position the sprite</s>
    <s>; The lower byte of the X-coordinate first</s>
    <kbd>lda</kbd> BALL0 + <var>2</var>
    <kbd>adc</kbd> #<var>104</var>
    <kbd>sta</kbd> SPR0X

    <s>; Then the high 9th bit: if the result of the add
    ; was over 255, the Carry flag will be set</s>
    <kbd>lda</kbd> SPRXHI
    <kbd>and</kbd> #%<var>11111110</var>
    <kbd>bcc</kbd> .xlow
    <kbd>eor</kbd> #<var>1</var> 
<var>.xlow</var>:
    <kbd>sta</kbd> SPRXHI

    <s>; And the Y-coordinate, which is always one byte</s>
    <s>; (Taking care to clear the Carry from earlier)</s>
    <kbd>lda</kbd> BALL0 + <var>4</var>
    <kbd>clc</kbd>
    <kbd>adc</kbd> #<var>58</var>
    <kbd>sta</kbd> SPR0Y

    <kbd>rts</kbd></pre>
</samp>
<p>If we do this for both the white and black balls, filling out <code>advance_white</code> as well as <code>advance_black</code>, each time around the game loop will move them by one step on-screen, which will look something like this:</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the above code: the balls continue on forever, outside the playing field, and loop back around">
  <source type="video/mp4" src="/content/img/c64-pongwars-spr1.mp4">
 </video>
 <figcaption>Figure 8: The above code running in VICE (at 3x speed)</figcaption>
</figure>
<p>So that's progress: the two balls can be seen moving, but they escape the playing field and wrap off the edge of the screen before returning, travelling forever in the same direction. This is, of course, because we have no code yet to detect the edge of the playing field and make a ball bounce when that's hit, so this is what we need next.</p>
<p>There are four possible conditions where a ball can hit an edge of the field and need to bounce, and they fall into two groups:</p>
<ul>
 <li>If a ball has hit the <strong>top</strong>, it was travelling up and needs to bounce down; conversely, if a ball has hit the <strong>bottom</strong>, it was travelling down and needs to bounce up.</li>
 <li>If a ball has hit the <strong>left</strong> edge, it was travelling to the left and needs to bounce off to the right; in the same fashion, a ball travelling right will hit the <strong>right</strong> edge and need to bounce back to the left.</li>
</ul>
<p>We know the coordinates of the ball (to be more precise, we know the coordinates of the top-left of the ball sprite) and we know the size of the field, so this becomes a relatively simple set of comparisons. The only caveat is that when we're checking for hits on the bottom or right edges, we're not comparing the top-left of the ball sprite, but the bottom-right, which is eight pixels further across in either direction.</p>
<p>So if the field is 20 blocks both ways, that's 160 pixels; if a ball's coordinate in either direction has reached 152, it's just hit the edge. In summary, we have the following four conditions in which a ball needs to bounce:</p>
<ul>
 <li>If a ball's <strong>Y-coordinate is 0</strong> it's hit the top;</li>
 <li>If a ball's <strong>Y-coordinate is 152</strong> it's hit the bottom;</li>
 <li>If a ball's <strong>X-coordinate is 0</strong> it's hit the left;</li>
 <li>If a ball's <strong>X-coordinate is 152</strong> it's hit the right.</li>
</ul>
<p>So what does it mean for the ball to bounce? You'll recall from Figure 6 that our ball's velocity is described by a unit vector: it's always moving at the same unit speed, but we keep track of its angle. So bounces are changes in angle: specifically, they're changes in angle caused by reflection.</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-reflect.png" alt="Reflection of a vector in the X- and Y-axes, showing the resultant change in angle">
 <figcaption>Figure 9: Reflections and their resultant angles<br>From Michael Corral, via OpenCurriculum<cite><sup>[9]</sup><mark><a href="https://opencurriculum.org/5485/rotations-and-reflections-of-angles/" target="_blank" rel="noreferrer">Michael Corral, "Rotations and Reflections of Angles"</a>, Sept 2020</mark></cite></figcaption>
</figure>
<p>In Figure 9, we see a reflection in the X-axis (hitting a horizontal line) causes the angle to negate, and reflection in the Y-axis (hitting a vertical) causes our angle &theta; to change to <em>180&deg; - &theta;</em>. For our purposes, you'll recall that &theta; ranges through 256 "degrees", so we can start to fill out code to perform these flips in angle, remembering that &theta; is stored in the first part of our ball's information block in memory:</p>
<samp>
 <pre><var>flipx_black</var>:
    <kbd>subroutine</kbd>
    <kbd>lda</kbd> #<var>0</var>       <s>; I have a reason for not using</s>
    <kbd>sec</kbd>          <s>; NEG here, we'll come to it</s>
    <kbd>sbc</kbd> BALL0
    <kbd>sta</kbd> BALL0
    <kbd>rts</kbd>

<var>flipy_black</var>:
    <kbd>subroutine</kbd>
    <kbd>lda</kbd> #<var>128</var>
    <kbd>sec</kbd>
    <kbd>sbc</kbd> BALL0
    <kbd>sta</kbd> BALL0
    <kbd>rts</kbd></pre>
</samp>
<p>And then we need to detect those collisions with the edge of the field, as described above, by filling out <code>collide_black</code>:</p>
<samp>
 <pre><var>collide_black</var>:
    <kbd>subroutine</kbd>

    <s>; Check the X-coord</s>
    <kbd>lda</kbd> BALL0 + <var>2</var>

    <s>; Skip if we haven't reached the left edge</s>
    <kbd>cmp</kbd> #<var>0</var>
    <kbd>bpl</kbd> .nobounce_x

    <s>; And if we haven't reached the right</s>
    <kbd>clc</kbd>
    <kbd>cmp</kbd> #<var>152</var>
    <kbd>bcc</kbd> .nobounce_x

    <s>; If we made it here, we need to flip</s>
    <s>; We've hit a vertical, flip in Y</s>
    <kbd>jsr</kbd> flipy_black

<var>.nobounce_x</var>:
    <s>; Check the Y-coord</s>
    <kbd>lda</kbd> BALL0 + <var>4</var>

    <s>; Skip if we haven't reached the top edge</s>
    <kbd>cmp</kbd> #<var>0</var>
    <kbd>bpl</kbd> .nobounce_y

    <s>; And if we haven't reached the bottom</s>
    <kbd>clc</kbd>
    <kbd>cmp</kbd> #<var>152</var>
    <kbd>bcc</kbd> .nobounce_y

    <s>; If we made it here, we need to flip</s>
    <s>; This time it's a horizontal</s>
    <kbd>jsr</kbd> flipx_black

<var>.nobounce_y</var>:
    <s>; TODO: Detect collisions with the other side</s>
    <kbd>rts</kbd></pre>
</samp>
<p>If we build the corresponding <code>collide_white</code> routine and its flip helpers, those will run with each frame, and we'll get something like this:</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the above code: the balls bounce around the playing field in well-worn paths">
  <source type="video/mp4" src="/content/img/c64-pongwars-bounce.mp4">
 </video>
 <figcaption>Figure 10: Balls bouncing around the playing field, in VICE (at 3x speed)</figcaption>
</figure>
<p>Now we're getting somewhere: a playing field, balls that bounce around it. What we don't have is any sense of unpredictability: the bounces are always perfect, the balls travel in well-worn paths forever, even if they're now constrained to the bounds of the field.</p>
<p>What we need is...</p>
<h2 id="_rand">An element of chance</h2>
<p>The original Pong Wars from Figure 1 has a sprinkle of randomness: each bounce (whether off the edge of the field or from an opposite-coloured block) is a reflection with a small offset to the angle, and it's this random offset that introduces the compelling infinite complexity.</p>
<p>To get the same effect on the Commodore 64, we could use BASIC's <code>RND</code> function to generate a pseudo-random number (as one might expect, this is referred to as Pseudo-Random Number Generation). There are two problems with this approach: being pseudo-random, the sequence is predictable so every run of this code would turn out the same; but more importantly for our purposes, <code>RND</code> is astonishingly slow at generating numbers, as it uses a relatively complex PRNG function.</p>
<p>On the C64, we have an alternative that's both fast and relatively simple to operate: hardware. The sound chip has three voices, and each of the voices can be set to one of four waveforms at an adjustable frequency: triangle, sawtooth, pulse or noise.</p>
<figure class="invertable">
 <img src="/content/img/c64-pongwars-sidwave.png" alt="The four waveforms of the C64 SID, a few cycles each">
 <figcaption>Figure 11: The four waveforms of the C64 SID<br>Philip Nelson, Compute! magazine, Feb 1985<cite><sup>[10]</sup><mark><a href="https://www.atarimagazines.com/compute/issue57/advanced_sound_effects.html" target="_blank" rel="noreferrer">"Advanced Sound Effects on the 64"</a>, Atari Magazines archive</mark></cite>
</figure>
<p>For our purposes, we can set up one of the SID's voices to generate noise, but disable <em>output of the voice</em> so we're not actually making the machine screech; we can then use the SID's internal representation of what's being generated as our source for random numbers.</p>
<p>Setup of the SID will need to be done as part of our general initialisation routine, so once again we're diving back into the <code>init</code> subroutine to set the SID's registers appropriately<cite><sup>[11]</sup><mark><a href="https://stackoverflow.com/questions/44937759/getting-random-number-from-6502-assembler" target="_blank" rel="noreferrer">"Getting random number from 6502 assember", 'Mike' at StackOverflow</a>, Jul 2017</mark></cite>:</p>
<samp>
 <pre>SID_3_FREQ = <var>$D40E</var>
SID_3_CTRL = <var>$D412</var>
SID_3_OUT = <var>$D41B</var>

<var>init</var>:
    <s>; ...
    ; After sprite data init, set up
    ; SID voice 3 for noise generation</s>

    <s>; Maximum frequency (65535)</s>
    <kbd>lda</kbd> #<var>255</var>
    <kbd>sta</kbd> SID_3_FREQ
    <kbd>sta</kbd> SID_3_FREQ + <var>1</var>

    <s>; Noise waveform, output disabled</s>
    <kbd>lda</kbd> #%<var>10000000</var>
    <kbd>sta</kbd> SID_3_CTRL</pre>
</samp>
<p>Now we can poll <code>SID_3_OUT</code> for hardware-generated real random numbers at any time, but they'll be a value that spans a full byte, anywhere from 0 to 255. We'd like to limit that range to our previously mentioned "small offset", which we can achieve fairly efficiently by lopping bits off the top end; more importantly, we'd like it to be a small offset either side of zero, which we can do by subtracting half the new range.</p>
<p>I've settled on cutting the value down from a 0-255 range to 0-15, which means we'll need to then subtract 8 to get a small random offset that's centred on zero. With that hived off into its own subroutine, we can adjust our reflection functions to use this random offset as the base instead of the fixed values 0 and 128:</p>
<samp>
 <pre><var>rand</var>:
    <s>; Generates a random number
    ; from -8 to +7, in A</s>
    <kbd>subroutine</kbd>
    <kbd>lda</kbd> SID_3_OUT
    <kbd>and</kbd> #%<var>00001111</var>
    <kbd>sec</kbd>
    <kbd>sbc</kbd> #<var>8</var>
    <kbd>rts</kbd></pre>
</samp>
<p></p>
<samp>
 <pre><var>flipx_black</var>:
    <kbd>subroutine</kbd>
    <kbd>jsr</kbd> rand
    <kbd>sec</kbd>
    <kbd>sbc</kbd> BALL0
    <kbd>sta</kbd> BALL0
    <kbd>rts</kbd>

<var>flipy_black</var>:
    <kbd>subroutine</kbd>
    <kbd>jsr</kbd> rand
    <kbd>clc</kbd>
    <kbd>adc</kbd> #<var>128</var>
    <kbd>sec</kbd>
    <kbd>sbc</kbd> BALL0
    <kbd>sta</kbd> BALL0
    <kbd>rts</kbd></pre>
</samp>
<p>With this adjustment in place, our eternal bouncing around the playing field looks a lot more interesting:</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the above code: the balls bounce around the playing field in randomised paths">
  <source type="video/mp4" src="/content/img/c64-pongwars-randbounce.mp4">
 </video>
 <figcaption>Figure 12: Balls bouncing in slightly offset directions, in VICE (at 3x speed)</figcaption>
</figure>
<h2 id="_field">The playing field</h2>
<p>So after (apparently) seven thousand words, we come to the point: these balls which we can now bounce around the playing field need to detect that they're about to hit a block of their colour, bounce off it, and flip the colour. We also need to render the blocks in the field, which we've deferred doing thus far in favour of showing the classic Commodore blue through the field.</p>
<p>Let's look at the second point first, and get the block data from our internal representation onto the screen. We actually have precedent for how to do that, since we set up the on-screen characters in rows of 20 during initialisation. We just need to do that again each time around the rendering loop, but with the colours this time (either black or white).</p>
<p>We get lucky here, because the C64's colour palette has black as colour 0 and white as 1: there's no work to do in translating the content of our internal representation to on-screen colours, except to copy the rows across. There is work, however, in the copying of data across: the C64 doesn't have a Direct Memory Access controller which could perform this copying in hardware, so the CPU has to do the work by picking up each value from the <em>source</em> and dropping it at the <em>destination</em>.</p>
<p>During initialisation we set up a pointer called <code>BLOCKPTR</code> which would advance as we came down the screen to render the character data in the rows. For rendering the blockfield's colours we can reuse this pointer as our <em>source</em>, and set up a new <code>COLORPTR</code> to act as our <em>destination</em>.</p>
<samp>
 <pre>COLORBUF = <var>$D800</var> + <var>40</var> + <var>10</var>
COLORPTR = <var>$05</var>    <s>; Two more unused bytes in zero-page</s>

<var>render_field</var>:
    <kbd>subroutine</kbd>
    
    <s>; First set up the pointers, src and dest</s>
    <kbd>lda</kbd> #&lt;BLOCKBUF
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> #&gt;BLOCKBUF
    <kbd>sta</kbd> BLOCKPTR + 1

    <kbd>lda</kbd> #&lt;COLORBUF
    <kbd>sta</kbd> COLORPTR
    <kbd>lda</kbd> #&gt;COLORBUF
    <kbd>sta</kbd> COLORPTR + 1

    <s>; Copying 20 rows of 20
    ; On the 6502 this gets a little confusing, because
    ; we want to use indirect indexed mode w/ pointers
    ; but that's only offered with the Y index</s>
    <kbd>ldx</kbd> #<var>20</var>       <s>; So X is the Y-coord</s>
<var>.copy_row</var>:
    <kbd>ldy</kbd> #<var>19</var>       <s>; And Y is the X-coord</s>
<var>.copy_blk</var>:
    <kbd>lda</kbd> (BLOCKPTR), y
    <kbd>sta</kbd> (COLORPTR), y

    <s>; We use the previous trick of counting down
    ; until Y goes negative, to save a comparison</s>
    <kbd>dey</kbd>
    <kbd>bpl</kbd> .copy_blk

    <s>; Advance to the next row in the blockfield
    ; Which is a 16-bit addition</s>
    <kbd>clc</kbd>
    <kbd>lda</kbd> BLOCKPTR
    <kbd>adc</kbd> #<var>20</var>
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> BLOCKPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; And advance in colour RAM, which importantly
    ; is 40 bytes down on-screen</s>
    <kbd>clc</kbd>
    <kbd>lda</kbd> COLORPTR
    <kbd>adc</kbd> #<var>40</var>
    <kbd>sta</kbd> COLORPTR
    <kbd>lda</kbd> COLORPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> COLORPTR + <var>1</var>

    <kbd>dex</kbd>
    <kbd>bne</kbd> .copy_row

    <kbd>rts</kbd></pre>
</samp>
<p>How does that look? Well, a little strange since the balls pass through their respective fields without affecting them, but that's to be expected: we've yet to write the code that detects collision there, the <code>TODO</code> from earlier is yet to be filled in.</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the above code: balls bounce over a playing field now in two colours">
  <source type="video/mp4" src="/content/img/c64-pongwars-bncfield.mp4">
 </video>
 <figcaption>Figure 13: Balls bouncing over a field that's half black and half white</figcaption>
</figure>
<p>Another way of saying that we need to detect collisions with the field is to find out which block resides at the location in the playing field the ball's about to reach. So for the black ball which should bounce off a black area of the field, the location the ball will reach after this next step would need to be in an area that's currently black. So we need a function to look up what's stored at the ball's location in the blockfield.</p>
<p>The ball's location is stored as pixel coordinates, so there are a few steps to get to where we need to go:</p>
<ul>
 <li>First, knock the pixel coordinates down to block coordinates in the field: divide by eight in both directions;</li>
 <li>Second, calculate <code>Y * 20 + X</code> to retrieve an entry from the blockfield storage.</li>
</ul>
<p>This is complicated by the CPU not having a native "multiply" instruction, so we need to perform some binary shifts and additions; for a primer on binary shifts, feel free to look over my introduction to those operators<cite><sup>[12]</sup><mark><a href="https://imrannazar.com/articles/bitwise-operators" target="_blank" rel="nofollower">"An Introduction to Bitwise Operators"</a>, Imran Nazar, Sep 2006</mark></cite> from 20 years ago. Essentially, because we can't natively multiply by 20, we need to generate the result through multiplying by binary powers and adding those results together; similarly, we can't natively divide by 8, so we do the same by shifting down. To take an example:</p>
<samp>
 <pre>       X = 58   |        Y = 133
       01101010 |        10000111
&gt;&gt; 1 = 00110101 | &gt;&gt; 1 = 01000011
&gt;&gt; 2 = 00011010 | &gt;&gt; 2 = 00100001
&gt;&gt; 3 = 00001101 | &gt;&gt; 3 = 00010000</pre>
</samp>
<p>With our coordinates in block-level values (in this case, BX=13 and BY=16), we can proceed to multiply and add; our formula here is <code>BY * 16 + BY * 4 + BX</code>, which in binary shifts is <code>BY &lt;&lt; 4 + BY &lt;&lt; 2 + BX</code>.</p>
<samp>
 <pre>       X = 58   |        Y = 133
       01101010 |        10000111
&gt;&gt; 1 = 00110101 | &gt;&gt; 1 = 01000011
&gt;&gt; 2 = 00011010 | &gt;&gt; 2 = 00100001
&gt;&gt; 3 = 00001101 | &gt;&gt; 3 = 00010000

                | &lt;&lt; 1 = 00100000
                | &lt;&lt; 2 = 01000000
                | &lt;&lt; 3 = 10000000  <s>; We should look at this</s>
                | &lt;&lt; 4 = 00000000</pre>
</samp>
<p>There are two things to take note of here. Firstly, our shift-left of 4 (to multiply by 16) has pushed a bit into the Carry flag because the value has gone over 255, so we need to treat this in much the same way we did wide additions earlier, by taking care to bring the Carry flag over to the high byte of the result. The CPU offers a <em>rotate</em> instruction which works much like a shift, but also brings in the Carry flag to one side of the accumulator and pushes a new value for Carry out the other side; we can use this to bring the Carry flag into the high byte of our resultant value.</p>
<p>The other thing to note is that by shifting right 3, and then shifting left 3, we're left with the value we started with except the bottom three bits are zeroed out. As the CPU only offers shift operations of one bit at a time, we can save a bunch of time by zeroing out those bits with an <code>AND</code> rather than perform the six shifts in question.</p>
<p>This makes our final calculation <code>((Y &amp; $F8) &lt;&lt; 1) + ((Y &amp; $F8) &gt;&gt; 1) + (X &gt;&gt; 3)</code>. Translating that over to 6502, we might get something like this.</p>
<samp>
<pre>SCRATCH = <var>$92</var>   <s>; Temp storage</s>

<s>; get_blk_val: Get the blockfield value at coordinates
; @param X Horizontal coordinate
; @param Y Vertical coordinate
; @return A The value of the block at this coordinate
; @clobbers A
; @preserves X, Y</s>
<var>get_blk_val</var>:
    <kbd>subroutine</kbd>

    <kbd>lda</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; ((Y &amp; $F8) &lt;&lt; 1)</s>
    <kbd>tya</kbd>
    <kbd>and</kbd> #$<var>F8</var>
    <kbd>asl</kbd>
    <kbd>sta</kbd> BLOCKPTR
    <kbd>rol</kbd> BLOCKPTR + <var>1</var>

    <s>; + ((Y &amp; $F8) &gt;&gt; 1)</s>
    <kbd>tya</kbd>
    <kbd>and</kbd> #$<var>F8</var>
    <kbd>lsr</kbd>
    <s>; 16-bit add to what's already in BLOCKPTR</s>
    <kbd>clc</kbd>
    <kbd>adc</kbd> BLOCKPTR
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> BLOCKPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; + (X &gt;&gt; 3)</s>
    <kbd>txa</kbd>
    <kbd>lsr</kbd>
    <kbd>lsr</kbd>
    <kbd>lsr</kbd>
    <kbd>clc</kbd>
    <kbd>adc</kbd> BLOCKPTR
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> BLOCKPTR + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; We need this as an index into BLOCKBUF</s>
    <kbd>clc</kbd>
    <kbd>lda</kbd> #&lt;BLOCKBUF
    <kbd>adc</kbd> BLOCKPTR
    <kbd>sta</kbd> BLOCKPTR
    <kbd>lda</kbd> #&gt;BLOCKBUF
    <kbd>adc</kbd> BLOCKPTR + <var>1</var>
    <kbd>sta</kbd> BLOCKPTR + <var>1</var>

    <s>; Finally, read from there
    ; We can only do this as a Y-indexed indirect,
    ; so we need to put Y into scratch memory</s>
    <kbd>sty</kbd> SCRATCH
    <kbd>ldy</kbd> #<var>0</var>
    <kbd>lda</kbd> (BLOCKPTR), y
    <kbd>ldy</kbd> SCRATCH

    <s>; Set Negative and Zero flags</s>
    <kbd>and</kbd> #$<var>FF</var>
    <kbd>rts</kbd></pre>
</samp>
<p>Having a way to check the value stored in the blockfield at a given coordinate, we now need to consider which points on the ball will need checking. As per Figure 4, the (0,0) coordinate of the ball sprite is actually empty space and wouldn't be a good point to detect a bounce; what's needed is to check a centre point on each of the edges, and those are:</p>
<ul>
 <li>(0,4) for the left edge;</li>
 <li>(7,4) for the right edge;</li>
 <li>(4,0) for the top;</li>
 <li>(4,7) for the bottom.</li>
</ul>
<p>For the purposes of this article, I'll show one of the more complicated options (collision of the right edge of the ball), as that involves addition on both axes; the other detections are left as an exercise for the reader. We pick up at the bottom of <code>collide_black</code> to check for collisions between the black ball and the black field:</p>
<samp>
 <pre><var>.nobounce_y</var>:
    <s>; Collision with the other side: right edge</s>
    <s>; First set up X and Y</s>
    <kbd>clc</kbd>
    <kbd>lda</kbd> BALL0 + <var>2</var>
    <kbd>adc</kbd> #<var>7</var>
    <kbd>tax</kbd>

    <kbd>clc</kbd>
    <kbd>lda</kbd> BALL0 + <var>4</var>
    <kbd>adc</kbd> #<var>4</var>
    <kbd>tay</kbd>

    <s>; Then check what block is here
    ; If it's 1 (white) we're still travelling
    ; For white/white collisions, we'd 'beq' here</s>
    <kbd>jsr</kbd> get_blk_val
    <kbd>bne</kbd> .nohit_r
    
    <s>; If we fell through to here, we've hit
    ; the black field; bounce off to the left
    ; (reflection in the Y-axis)</s>
    <kbd>jsr</kbd> flipy_black
    <s>; TODO: Change state of the struck block</s>
    <kbd>jsr</kbd> flipblk

<var>.nohit_r</var>:
    <s>; Other edge detections</s></pre>
</samp>
<p>That <em>almost</em> gets us what we need: we can detect that the field has been hit, we can bounce off, but the block that's been hit doesn't change colour. That's the last <code>TODO</code> left for ourselves at the bottom of <code>collide_black</code>; fortunately, it's fairly simple. We already know which block is involved (we calculated <code>BLOCKPTR</code> earlier as part of <code>get_blk_val</code>'s processing), and we know that the colour always flips (either white to black or black to white), so this is always an XOR operation.</p>
<samp>
 <pre><s>; flipblk: Flip the block pointed to by BLOCKPTR
; @clobbers A, Y</s>
<var>flipblk</var>:
    <kbd>ldy</kbd> #<var>0</var>
    <kbd>lda</kbd> (BLOCKPTR), y
    <kbd>eor</kbd> #%<var>00000001</var>
    <kbd>sta</kbd> (BLOCKPTR), y
    <kbd>rts</kbd></pre>
</samp>
<p>Filling out the other edge detection cases, and copying the whole set over to processing for the white ball, we arrive at a final effect, with only the rendering of the scores for each side left to consider.</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the final effect: balls bounce over a playing field, hit the other side, and flip colours in the field">
  <source type="video/mp4" src="/content/img/c64-pongwars-effect.mp4">
 </video>
 <figcaption>Figure 14: Balls bouncing, hitting the other field, and flipping blocks (at 4x speed)</figcaption>
</figure>
<h2 id="_score">Keeping score</h2>
<p>The last piece of the puzzle is calculating the scores for each side, and getting those on-screen below the playing field. The first of these points is relatively simple: as we're already copying the block field over from our internal storage to the video chip's colour RAM to get it rendered, we can take that opportunity to count the blocks as they come through. The only complication is that it's possible for one side to have more than 255 blocks, so these are 16-bit counters and need to be treated appopriately (with 16-bit additions).</p>
<p>Picking up in the middle of <code>render_field</code>, in the tightest level of the copying loop:</p>
<samp>
 <pre>CNTBLK = <var>$FB</var>
CNTWHT = <var>$FD</var>

<var>render_field</var>:
    <s>...</s>
<var>.copy_blk</var>:
    <kbd>lda</kbd> (BLOCKPTR), y

    <s>; We're about to clobber A, hold onto it</s>
    <kbd>pha</kbd>

    <s>; If we loaded a 1, this is a white field
    ; The Z flag will be cleared, so BNE will jump over</s>
    <kbd>bne</kbd> .copy_cntwht

    <s>; If we end up here, the block is 0 (black)</s>
<var>.copy_cntblk</var>:
    <kbd>inc</kbd> CNTBLK
    <kbd>lda</kbd> CNTBLK + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> CNTBLK + <var>1</var>
    <kbd>jmp</kbd> .copy_write

    <s>; If we land here, we had a 1 (white)</s>
<var>.copy_cntwht</var>:
    <kbd>inc</kbd> CNTWHT
    <kbd>lda</kbd> CNTWHT + <var>1</var>
    <kbd>adc</kbd> #<var>0</var>
    <kbd>sta</kbd> CNTWHT + <var>1</var>

<var>.copy_write</var>:
    <s>; Back to writing to the color RAM</s>
    <kbd>pla</kbd>
    <kbd>sta</kbd> (COLORPTR), y</pre>
</samp>
<p>This gives us a way to count up the scores each side, whenever the blockfield is rendered; what's needed next is a way to get those counts on screen. As with a few other things we've come across in our journey, Commodore BASIC has routines which would allow us to print out a number, but there are caveats around performance. While we're working at this low level, let's have a look at what it would take to print out a number using a routine in assembly.</p>
<p>Let's say one of our scores to print is <code>279</code>: this needs to be taken from a 16-bit value in memory to three distinct characters on screen (<code>"2" "7" "9"</code>). The mathematical principle is fairly simple, and is one we all come across in elementary school: repeated division, which provides us our digits in reverse order.</p>
<samp>
 <pre>279 &div; 10 = 27 remainder 9
 27 &div; 10 =  2 remainder 7
  2 &div; 10 =  0 remainder 2</pre>
</samp>
<p>There are two complicating factors here. First, we can't simply send the value <code>2</code> to the screen; as per Figure 3, this character code represents the letter B, as the Commodore 64's character ROM doesn't start with the numeric digits. We need to add 48 to each digit as it comes out of the division, in order to get a character string that can go on-screen.</p>
<p>The second complication is that the processor doesn't offer division natively (we already saw earlier that native multiplication is not a thing either), so a software routine is needed to perform 16-bit division on our behalf. Fortunately, the basic algorithm for division is eminently possible to wrap one's head around, and is essentially a binary version of the classic "long division" we all suffered through in math class.</p>
<h2 id="_div">Digression the third: Binary long division</h2>
<p>Just as a multiplication is repeated addition, a division can be thought of as repeated subtraction. Let's break down that first division in more detail, the way one might be taught to do division in school:</p>
<samp>
 <pre>279 &div; 10:
Does  2 go into 10? No
Does 27 go into 10? Yes, 2x

27 - (2 x 10) = 7

Tack on the rest of the number, continue with: 79

Does  7 go into 10? No [but we know that, it was left over]
Does 79 go into 10? Yes, 7x

79 - (7 x 10) = 9

Tack on the rest of the number, continue with:  9

Does 9 go into 10? No [but we know that, it was left over]
No further digits, abort</pre>
</samp>
<p>This eventually yields our intended result: combining the individual "does it go into" questions gives 27, while 9 was left over. When it comes to doing this on a computer, we have to knock these operations down into binary, so the pulling in of each digit looks slightly different. The fact that we're working in binary, though, means that our "does it go into" question can only ever yield two results: "No" or "Yes, 1x". That means our question becomes "is greater than or equal to":</p>
<samp>
 <pre>100010111 &div; 1010:
    1 &ge; 1010? No
   10 &ge; 1010? No
  100 &ge; 1010? No
 1000 &ge; 1010? No
10001 &ge; 1010? Yes

10001 - (1 x 1010) = 111

Tack on the rest of the number, continue with: 1110111

  111 &ge; 1010? No [we know it won't]
 1110 &ge; 1010? Yes

 1110 - (1 x 1010) = 100

Tack on the rest of the number, continue with: 100111

  100 &ge; 1010? No [we know it won't]
 1001 &ge; 1010? No
10011 &ge; 1010? Yes

10011 - (1 x 1010) = 1001

Tack on the rest of the number, continue with: 10011

 1001 &ge; 1010? No [we know it won't]
10011 &ge; 1010? Yes

10011 - (1 x 1010) = 1001

Tack on the rest of the number, continue with: 1001

 1001 &ge; 1010? No [we know it won't]
No further digits, abort</pre>
</samp>
<p>Now, this looks like a longer operation, but that's only because it's happening in a lower base: that means each step down is a step by two, rather than 10. If we now count up the "No" and "Yes" answers, ignoring the "No" answers where we know the answer was left over from the previous step, we get a result of: <code>000011011</code> remainder <code>1001</code>. Coming back up to decimal, that's 27 remainder 9.</p>
<p>Before we can implement this on the C64, there are two things we need to work out: first, how do we "shift" each digit over to incrementally perform the "greater than or equal to" check? It turns out there's an instruction to do exactly that, "arithmetic shift left" (<code>asl</code>) which will push the top bit out into the Carry flag. Except we don't want the top bit to land in the Carry flag, we'd like it in the accumulator where we can work on the value; we can thus combine <code>asl</code> with "rotate left" (<code>rol</code>) which pulls the Carry flag into the bottom of a value, and pushes a corresponding bit out the top.</p>
<p>Thus, to work on a 16-bit value, we want to perform a <em>24-bit left shift</em> to get the value passing through both bytes and the accumulator:</p>
<samp>
 <pre>DIVIDEND = <var>$1B</var>
DIVISOR  = <var>$19</var>

<s>; Divide a 16-bit value by an 8-bit divisor
; @clobbers A, X</s>
<var>div16_8</var>:
    <kbd>subroutine</kbd>
    <kbd>ldx</kbd> #<var>16</var>
    <kbd>lda</kbd> #<var>0</var>
<var>.loop</var>:
    <kbd>asl</kbd> DIVIDEND
    <kbd>rol</kbd> DIVIDEND + <var>1</var>
    <kbd>rol</kbd> a

    <s>; ...What do we do here?</s>

    <kbd>dex</kbd>
    <kbd>bne</kbd> .loop
    <kbd>rts</kbd></pre>
</samp>
<p>The other issue is our &ge; check, which documentation for the processor<cite><sup>[13]</sup><mark><a href="https://6502.org/tutorials/compare_instructions.html" target="_blank" rel="nofollower">"Compare Instructions", from "6502 Software Design" by Leo Scanlon</a>, updated Dec 2022</mark></cite> tells us can be achieved by using <code>cmp</code> ("compare", which performs a subtraction and throws the result away), and <code>bcs</code> ("branch if carry set"). In this instance, we actually want to skip <em>over</em> the subtraction if not required, so we'll use <code>bcc</code> instead:</p>
<samp>
 <pre>    <kbd>cmp</kbd> DIVISOR
    <kbd>bcc</kbd> .no_sub
    <kbd>sbc</kbd> DIVISOR
    <s>; ...And where do we put the Yes result?</s></pre>
</samp>
<p>As we shift our dividend through, we leave zeroes behind: when this loop is finished, <code>DIVIDEND</code> will be left zeroed out entirely. Conversely, we need to store our result somewhere, incrementally shifting bits of that over to match our progress through the dividend. We can combine these two steps, and store the result at the bottom of the dividend <em>at the same time</em> that the top is shifting through.</p>
<p>All we need to do that is to either set or not set the bottom bit of the dividend:</p>
<samp>
 <pre>    <kbd>cmp</kbd> DIVISOR
    <kbd>bcc</kbd> .no_sub
    <kbd>sbc</kbd> DIVISOR
    <kbd>inc</kbd> DIVIDEND
<var>.no_sub</var>:
    <s>; ...And the go-around for the loop</s></pre>
</samp>
<p>This has the additional subtle advantage that our result is in the same place in memory that our dividend started, meaning it can be used immediately for another division without having to be copied over from somewhere. That's exactly what we were looking for, as we want to perform repeated division to work out the digits for our score display.</p>
<p>Putting these disparate snippets together, we get a final division subroutine which looks like this<cite><sup>[C]</sup><mark>I take no credit for this implementation, only for the above dissection of how it works; this comes from <a href="https://forums.nesdev.org/viewtopic.php?p=895&sid=f8ac1dde19c7962bf8f2b6e897cb5769#p895" target="_blank" rel="nofollower">a post on the NESDev forums</a> by "tepples" from Jan 2005.</mark></cite>:</p>
<samp>
 <pre>DIVIDEND = <var>$1B</var>
DIVISOR  = <var>$19</var>

<s>; Divide a 16-bit value by an 8-bit divisor
; @param Memory (DIVIDEND, DIVISOR)
; @return Memory (DIVIDEND): The result
; @return A The remainder
; @clobbers A, X</s>
<var>div16_8</var>:
    <kbd>subroutine</kbd>
    <kbd>ldx</kbd> #<var>16</var>
    <kbd>lda</kbd> #<var>0</var>
<var>.loop</var>:
    <kbd>asl</kbd> DIVIDEND
    <kbd>rol</kbd> DIVIDEND + <var>1</var>
    <kbd>rol</kbd> a
    <kbd>cmp</kbd> DIVISOR
    <kbd>bcc</kbd> .no_sub
    <kbd>sbc</kbd> DIVISOR
    <kbd>inc</kbd> DIVIDEND
<var>.no_sub</var>:
    <kbd>dex</kbd>
    <kbd>bne</kbd> .loop
    <kbd>rts</kbd></pre>
</samp>
<h2 id="_rscore">Rendering the score</h2>
<p>Now we have a routine for division, we can perform our repeated dividing-by-10 in order to build a score string to display on-screen. We'll need a little helper subroutine to build the string by adding 48 to each digit, as mentioned beforehand: we know that, these being 16-bit numbers, they can never go past <code>65535</code> decimal, which means we need to allocate a block of five bytes in memory to hold the resultant string.</p>
<p>Of course, this brings up more questions for us: how do we know how long the string is once it's generated, and what happens if the score for one side changes from, say, 100 down to 99? If we only print the <code>99</code>, one character from the previous score will be left on-screen and we'll wne up with (depending on the side) <code>990</code> or <code>199</code> as the visible score.</p>
<p>The first of these issues can be resolved by always using a fixed length of five bytes for the string, and pre-filling the string with spaces so that when we print it out, the "blank" characters don't otherwise affect the display. Similarly, the second issue can be resolved by always printing spaces over the screen area for the scores before we write out the scores themselves, so the display is always fresh.</p>
<p>The first thing we'll need, then, is a subroutine to convert the score to a string, by repeated division:</p>
<samp>
 <pre>STROUT = <var>$22</var>

<s>; int2str: Convert 16-bit integer to string
; @param A Zero-page location of the number
; @clobbers A, X, Y</s>
<var>int2str</var>:
    <kbd>subroutine</kbd>

    <s>; Firstly, setup the division routine</s>
    <kbd>tax</kbd>
    <kbd>lda</kbd> <var>0</var>, x
    <kbd>sta</kbd> DIVIDEND
    <kbd>lda</kbd> <var>1</var>, x
    <kbd>sta</kbd> DIVIDEND + <var>1</var>

    <kbd>lda</kbd> #<var>10</var>
    <kbd>sta</kbd> DIVISOR

    <s>; Then blank out the string storage
    ; Five bytes, from STROUT + 4 to STROUT + 0</s>
    <kbd>ldx</kbd> #<var>4</var>
    <kbd>lda</kbd> #<var>32</var>   <s>; Space</s>
<var>.buflp</var>:
    <kbd>sta</kbd> STROUT, x
    <kbd>dex</kbd>
    <kbd>bpl</kbd> .buflp

    <s>; And begin dividing
    ; We use the Y index here, as div clobbers X</s>
    <kbd>ldy</kbd> #<var>4</var>
<var>.divlp</var>:
    <kbd>jsr</kbd> div16_8

    <s>; Our remainder is the digit to print, we need
    ; to offset this into the PETSCII numerals</s>
    <kbd>clc</kbd>
    <kbd>adc</kbd> #<var>48</var>
    <kbd>sta</kbd> STROUT, y
    <kbd>dey</kbd>

    <s>; We don't want to go the full 5 characters
    ; Abort if the dividend is zero</s>
    <kbd>lda</kbd> DIVIDEND
    <kbd>ora</kbd> DIVIDEND + <var>1</var>
    <kbd>bne</kbd> .divlp

    <kbd>rts</kbd></pre>
</samp>
<p>And now all that remains is to get these strings on-screen. We'll want to perform the blanking operation mentioned earlier, to overwrite the previous score with spaces, and then there's one final wrinkle to consider: these strings are space-padded to the left (which means, for example, a score of 274 is held in memory as <code>&nbsp;&nbsp;274</code>), but if we want to print the score lined up with the edge of the blockfield that means the left-hand side will be indented from the left edge.</p>
<p>All we need to do for this case is to ignore spaces as they come through, and only print non-space values. On the right-hand side, we <em>do</em> want to print those spaces as they go through (otherwise we'll have the opposite problem, an indent on the right), so there are two related but different sections of code in <code>render_score</code>:</p>
<samp>
 <pre><var>render_score</var>:
    <s>; Firstly, blank out the scores
    ; Screen row 22, positions 10-14 and 25-29</s>
    <kbd>ldx</kbd> #<var>4</var>
    <kbd>lda</kbd> #<var>32</var>
<var>.blank</var>:
    <kbd>sta</kbd> SCRRAM + <var>22</var> * <var>40</var> + <var>14</var>, x
    <kbd>sta</kbd> SCRRAM + <var>22</var> * <var>40</var> + <var>25</var>, x
    <kbd>dex</kbd>
    <kbd>bpl</kbd> .blank

    <s>; Then print the black score, ignoring spaces
    ; Note: We want the <em>address</em> of
    ; the score, not its value, in A</s>
    <kbd>lda</kbd> #CNTBLK
    <kbd>jsr</kbd> int2str

    <s>; We can't use our trick of looping backwards
    ; as the score will then print out backwards
    ; so X runs from 0 to 4, and aborts at 5</s>
    <kbd>ldx</kbd> #<var>0</var>
    <kbd>ldy</kbd> #<var>0</var>

<var>.black_print</var>:
    <kbd>lda</kbd> STROUT, x
    <kbd>cmp</kbd> #<var>32</var>
    <kbd>beq</kbd> .black_skip
    <kbd>sta</kbd> SCRRAM + <var>22</var> * <var>40</var> + <var>10</var>, y
    <kbd>iny</kbd>
<var>.black_skip</var>:
    <kbd>inx</kbd>
    <kbd>cpx</kbd> #<var>5</var>
    <kbd>bne</kbd> .black_print

    <s>; The same again for white
    ; Simpler this time, we can print spaces</s>
    <kbd>lda</kbd> #CNTWHT
    <kbd>jsr</kbd> int2str
    <kbd>ldy</kbd> #<var>0</var>
<var>.white_print</var>:
    <kbd>lda</kbd> STROUT, y
    <kbd>sta</kbd> SCRRAM + <var>22</var> * <var>40</var> + <var>25</var>, y
    <kbd>iny</kbd>
    <kbd>cpy</kbd> #<var>5</var>
    <kbd>bne</kbd> .white_print

    <kbd>rts</kbd></pre>
</samp>
<p>With that final piece of the rendering routine in place, we get the full mesmerising effect of Pong Wars, which we can leave to run at the highest speed VICE can attain on my machine (somewhere around 10x realtime):</p>
<figure>
 <video controls loop muted preload="auto" aria-label="Recording from VICE of the final effect with score: balls bounce over a playing field, hit the other side, and flip colours in the field">
  <source type="video/mp4" src="/content/img/c64-pongwars-final.mp4">
 </video>
 <figcaption>Figure 15: The final Pong Wars effect with printed scores (at 4x speed, then at VICE's Warp setting)</figcaption>
</figure>
<h2 id="_future">Future considerations, or "why so slow?"</h2>
<p>The astute reader will have noted throughout this post that the video output has come from a copy of VICE running at 3x (or 4x, in some cases) speed. Right at the top of this post, I stated:</p>
<blockquote>...we'll be looking to try to limit any calculations needed for this animation, so they're completed within the blanking period.</blockquote>
<p>So where's the disconnect? Why is this effect so slow in its current implementation, that it takes VICE running at multiple times native speed to get it looking half-decent?</p>
<p>As it turns out, the calculations being made to detect bounces are relatively efficient, and complete within the period we need; the problem is that we then copy the blockfield across to screen memory to get it rendered, and calculate the current score by counting up the number of black and white blocks that are copied across. This takes an astonishing amount of time: more or less an entire frame is taken up by this copy-and-count process and the divisions required to print the score afterwards.</p>
<p>That means rather than running at the C64's native 60 frames per second, this effect runs at 30. On top of this slowdown, the balls move by 1 pixel per go-around, which is a slow speed in itself when travelling the distance of the blockfield: the initial directions of the balls are such that it'll be at least five seconds before they hit the first block and the Pong War begins.</p>
<p>There are a bunch of improvements we could make to the effect, which won't be performed here, but can be briefly discussed:</p>
<ul>
 <li><strong>Direct rendering</strong>: Rather than copy the blockfield over to colour RAM with each render, colour RAM itself can be used as the blockfield storage as it allows for both read and write from the CPU without performance penalty. The only caveat here is that <code>get_blk_val</code> (the routine which retrieves the colour at a given coordinate) will need to multiply by 40 instead of 20, to account for the rows not being consecutive in memory.</li>
 <li><strong>Score-keeping at collision time</strong>: In this implementation we've been using the naive method of counting the black and white blocks at the time they're being copied into colour RAM. We can instead keep track of the scores for each side as we know they start at 200 each, and only ever change when flipped by collision with a ball; this would be a change in <code>flipblk</code> to perform a 16-bit addition of 1 for one side, and subtraction of 1 for the other, whenever a block flips.</li>
 <li><strong>Score-rendering at collision time</strong>: The divisions involved in taking the counted-up scores and printing them out digit by digit are also significant in terms of CPU time, and don't need to run every frame; as that area of the screen only changes when a collision happens, it's possible to perform that work alongside the change in score-keeping, breaking up our rendering routine so some of it doesn't happen every frame.</li>
 <li><strong>Longer ball vector</strong>: With these speedups in place, the effect is likely to run at the native 60fps, and the balls can then be made to move further with each frame by lengthening their stride. For a vector of length 2, this would simply mean running <code>advance_black</code> and <code>collide_black</code> (and their corresponding white functions) twice before rendering each time.</li>
</ul>
<p>But for my first for-real Commodore 64 program, I think we did okay.</p>
<h2 id="_cites">Footnotes and citations</h2>
<p><em>The below notes are also presented inline in the main body of this post, but are replicated here for those who prefer their citations as endnotes.</em></p>
<p>
 <ul style="list-style:none inside">
  <li><sup>[0]</sup>: <a href="https://hachyderm.io/@Two9A/111974181833797753" target="_blank" rel="nofollower">Pongwars on the C64</a>, @Two9A, Feb 22nd 2024</li>
  <li><sup>[1]</sup>: <a href="https://hachyderm.io/@vnglst/111828811496422610" target="_blank" rel="nofollower">Pongwars recreated in JavaScript</a>, @vnglst, Jan 2024</li>
  <li><sup>[2]</sup>: <a href="https://imrannazar.com/articles/commodore-1541" target="_blank" rel="nofollower">"Why Was the Commodore 64 Disk Drive So Slow?"</a>, Imran Nazar, Dec 2024</li>
  <li><sup>[3]</sup>: <a href="https://www.c64-wiki.com/wiki/Raster_interrupt" target="_blank" rel="nofollower">"Raster interrupt"</a>, C64 Wiki, updated Mar 2024</li>
  <li><sup>[4]</sup>: <a href="https://sta.c64.org/cbm64mem.html" target="_blank" rel="nofollower">Commodore 64 memory map</a>, STA, last updated probably a while ago as the page is HTML 4.01</li>
  <li><sup>[5]</sup>: <a href="https://www.c64-wiki.com/wiki/Character_set" target="_blank" rel="nofollower">"Character set"</a>, C64 Wiki, updated Aug 2025</li>
  <li><sup>[6]</sup>: <a href="https://donatstudios.com/PixelCircleGenerator" target="_blank" rel="nofollower">"Pixel Circle Generator"</a>, Donat Studios, updated Jul 2025</li>
  <li><sup>[7]</sup>: <a href="https://github.com/dasm-assembler/dasm/" target="_blank" rel="noreferrer">dASM assembler</a>, GitHub, last release 2020</li>
  <li><sup>[8]</sup>: <a href="https://lemmings.info/rasters-sprites-and-multiplexing/" target="_blank" rel="noreferrer">"Raster's, Sprites and Multiplexing"</a>, Mark Dailly, Jul 2024</li>
  <li><sup>[9]</sup>: <a href="https://opencurriculum.org/5485/rotations-and-reflections-of-angles/" target="_blank" rel="noreferrer">Michael Corral, "Rotations and Reflections of Angles"</a>, Sept 2020</li>
  <li><sup>[10]</sup>: <a href="https://www.atarimagazines.com/compute/issue57/advanced_sound_effects.html" target="_blank" rel="noreferrer">"Advanced Sound Effects on the 64"</a>, Atari Magazines archive</li>
  <li><sup>[11]</sup>: <a href="https://stackoverflow.com/questions/44937759/getting-random-number-from-6502-assembler" target="_blank" rel="noreferrer">"Getting random number from 6502 assember", 'Mike' at StackOverflow</a>, Jul 2017</li>
  <li><sup>[12]</sup>: <a href="https://imrannazar.com/articles/bitwise-operators" target="_blank" rel="nofollower">"An Introduction to Bitwise Operators"</a>, Imran Nazar, Sep 2006</li>
  <li><sup>[13]</sup>: <a href="https://6502.org/tutorials/compare_instructions.html" target="_blank" rel="nofollower">"Compare Instructions", from "6502 Software Design" by Leo Scanlon</a>, updated Dec 2022</li>
 </ul>
 <ul style="list-style: none inside">
  <li><sup>[A]</sup>: A nybble is four bits, as opposed to an 8-bit byte.</li>
  <li><sup>[B]</sup>: I'm using <a href="https://vice-emu.sourceforge.io/" target="_blank" rel="noreferrer">VICE</a> [to emulate the C64] here, which is perhaps the most accurate emulator of anything ever built.</li>
  <li><sup>[C]</sup>: I take no credit for this implementation [of binary division], only for the above dissection of how it works; this comes from <a href="https://forums.nesdev.org/viewtopic.php?p=895&sid=f8ac1dde19c7962bf8f2b6e897cb5769#p895" target="_blank" rel="nofollower">a post on the NESDev forums</a> by "tepples" from Jan 2005.</li>
 </ul>
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Drag</title>
 <link href="https://imrannazar.com/writings/drag" rel="alternate" type="text/html" title="Drag" />
 <id>https://imrannazar.com/writings/drag</id>
 <summary>Y2K-inspired science fiction in the Terminator universe: A cult tries to wait out the coming nuclear holocaust in an orbital station, but something catches them by surprise.</summary>
 <category term="Original Writings" />
 <published>Wed, 08 Jul 2026 09:30:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>Originally posted <a href="https://hachyderm.io/@Two9A/116883596369674994" target="_blank" rel="nofollower">on Mastodon</a></em></p>
<p>Some knew in advance that Skynet was growing geometrically. The Cult of the Human Renaissance had spent years (and a lot of political capital) piggybacking Shuttle launches to build a lifeboat that could remain in orbit with a few hundred inhabitants before the inevitable end came for the billions below.
<p>When the acute fallout had died back, the theory held, those left above could return to Earth as rulers of the ashes. There were problems with the theory, sure, but the Renaissance held true to its belief that the machines would simply admit defeat when met with their obvious betters.
<p>August 1997 came and went, the world was enveloped in nuclear fire, and the Cult watched idly from their orbital vantage point. Thirty years up here, and they could emerge triumphant.
<p>The months passed slowly in orbit, until the end of 1999. The station performed regular boosts to retain elevation, against the ever-so-slight drag of the wisps of atmosphere that were still present up here.
<p>Until the Cult woke up on Jan 1, 2000, to find an error on the primary navigation display:</p>
<samp><pre>Component can't create object
Failed on creation from object context: CoCreateInstance (ProgId:
ADODB.Connection.2.0) (CLSID: {00000514-0000-0010-8000-00AA006D2EA4})</pre></samp>
<p>See, all that lobbying to get space on launches, and the Cult's own human rocketry program, had meant they were strapped when it came to design and fit-out of the lifeboat itself. Mechanically it was sound and held pressure, but the navigation and station-keeping software was farmed out to third parties.
<p>After three rounds of sub-sub-contracting, the work was done by a software engineer at a bank in South Korea. Or well, that was their day job; on the side, they reused much of the code for whatever jobs were going on Mechanical Turk.
<p>And the day job was maintenance and new features for an ActiveX plugin for the bank, in Internet Explorer 4.01. The latest and greatest at the time of launch, but still not patched for the Y2K bug.
<p>The millennium came, and station-keeping failed on the lifeboat. Unable to counter atmospheric drag, the Cult of the Human Renaissance came to a fiery end on August 29th 2000, three years to the day after the end of the world.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Adventures in Songwriting: Translating &#039;Delge&ccedil;&#039;</title>
 <link href="https://imrannazar.com/writings/lyrics/delgec" rel="alternate" type="text/html" title="Adventures in Songwriting: Translating &#039;Delge&ccedil;&#039;" />
 <id>https://imrannazar.com/writings/lyrics/delgec</id>
 <summary>Another translation attempt, this time of one of &amp;#x015e;ebnem Ferah&#039;s deep cuts; the aim here is to convey meaning while retaining rhyme and meter, while not necessarily being a transliteration.</summary>
 <category term="Original Writings" />
 <published>Fri, 17 Apr 2026 23:53:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Another attempt at translating a hit from the 2000's-era classics of Turkish rock: this time it's <em>Delge&ccedil;</em> from &#x015e;ebnem Ferah's seminal <em>Can K&#x0131;r&#x0131;klar&#x0131;</em>. &#x015e;ebnem's a lot more metaphorical in her lyrics than Mor ve &Ouml;tesi who I translated last time<cite><sup>[1]</sup><mark><a href="https://imrannazar.com/writings/lyrics/bir-derdim-var" target="_blank" rel="noreferrer">"Adventures in Songwriting: Translating 'Bir Derdim Var'", Mar 2026</a></mark></cite>; I've taken appropriate licence to try to convey the meaning while retaining what I can of poetic meter.</p>
<p><em>This is not a transliteration.</em></p>
<figure>
 <iframe width="560" height="315" src="https://www.youtube.com/embed/LOTP4Vqe5ZE" title="YouTube embed" frameborder="0" allow="autoplay; encrypted-media; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
 <figcaption>The reference track</figcaption>
</figure>
<p><em>Gel bir par&ccedil;am ol, kan&#x0131;mdan, can&#x0131;mdan</em><br>
Tear a piece off me, take a corner of my heart</p>
<p><em>Gel bir par&ccedil;a al, ekme&#x011f;imden suyumdan</em><br>
Take your pound of flesh, tear my bread and me apart</p>
<p><em>Ben zaten d&uuml;&#x015fm&uuml;&#x015f;&uuml;m, kald&#x0131;r&#x0131;mlar yata&#x011f;&#x0131;m olmu&#x015f;</em><br>
Already down and out, the sidewalk as my place of rest</p>
<p><em>Gel, bir de sen vur; hadi gel, bir de sen vur</em><br>
Go 'head and kick me, while I'm down come and kick me</p>
<p><em>Ben zaten d&uuml;&#x015fm&uuml;&#x015f;&uuml;m, i&ccedil;im d&#x0131;&#x015f;&#x0131;m korku dolmu&#x015f;</em><br>
Already down and out, fear building up within my chest</p>
<p><em>Gel, bir de sen vur; hadi gel</em><br>
Go 'head and kick me, while I'm down</p>
<p><em>Nas&#x0131;l olsa al&#x0131;&#x015f;t&#x0131;m ben, bu sert ruzg&acirc;rlara</em><br>
Somehow I thought I'd gotten used to walking into the wind</p>
<p><em>Bu sert iklimli &#x0131;ss&#x0131;z hayata</em><br>
Cutting at me 'til I'm paper thin</p>
<p><em>Delge&ccedil; gibi deleceksin, sen de ruhumu</em><br>
Then you fold round like a holepunch, shredding at my life</p>
<p><em>Biliyorum durma, gel</em><br>
You know you want to twist the knife</p>
<p><em>Bir de sen vur, bir de sen vur</em><br>
Come and kick me, while I'm down come and kick me</p>
<p><em>Gel, bir de sen vur; bir de sen vur</em><br>
Twist the knife, come and kick me; while I'm down come and kick me</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Adventures in Songwriting: Translating &#039;Bir Derdim Var&#039;</title>
 <link href="https://imrannazar.com/writings/lyrics/bir-derdim-var" rel="alternate" type="text/html" title="Adventures in Songwriting: Translating &#039;Bir Derdim Var&#039;" />
 <id>https://imrannazar.com/writings/lyrics/bir-derdim-var</id>
 <summary>An attempt to translate Mor ve &amp;Ouml;tesi&#039;s classic of Turkish rock while keeping to the melodic line of the song, and retaining some sense of lyrical rhyme.</summary>
 <category term="Original Writings" />
 <published>Mon, 30 Mar 2026 22:43:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>An attempt at translating Mor ve &Ouml;tesi's <em>Bir Derdim Var</em>, a classic of Turkish rock, while keeping to the melodic line of the song, and retaining some sense of lyrical rhyme.</p>
<figure>
 <iframe width="560" height="315" src="https://www.youtube.com/embed/7RW8n4iXZbA" title="YouTube embed" frameborder="0" allow="autoplay; encrypted-media; picture-in-picture" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
 <figcaption>The reference track</figcaption>
</figure>
<table>
 <tr>
  <td style="white-space:pre"><em>Bir derdim var, art&#x0131;k
Tutamam i&ccedil;inde
Gitsem nereye kadar?
Kalsam neye yarar?
Hi&ccedil; anlatamad&#x0131;m,
hi&ccedil; anlamad&#x0131;lar
Herkes neden d&uuml;&#x015f;man,
herkes neden d&uuml;&#x015f;man?
Unuttuk hepsini,
Nuh'un nefesini
Gelme yan&#x0131;ma,
sen ba&#x015f;kas&#x0131;n, ben ba&#x015f;ka

Bir derdim var, art&#x0131;k
Tutamam i&ccedil;inde
Gitsem nereye kadar?
Kalsam neye yarar?
Hi&ccedil; anlatamad&#x0131;m,
hi&ccedil; anlamad&#x0131;lar

Bak, bu son perde oyun yok,
bundan sonra &#x0131;&#x015f;&#x0131;k yok,
hi&ccedil;bir &#x015f;ey yok
Yok, yok, yok

Bir derdim var
Bir derdim var
Bir derdim var i&ccedil;inde

Bir derdim var, art&#x0131;k
Tutamam i&ccedil;inde</em></td>
  <td style="white-space:pre">There's something wrong up here
I can't keep it in me
If I leave where would I go?
If I stay would they even know?
I couldn't make them see,
They'd never understand
Why do I see enemies,
Why do I see enemies?
We've forgotten the light
The breath Noah gave to life
Don't come up next to me
You're some different species

There's something wrong up here
I can't keep it in me
If I leave where would I go?
If I stay would they even know?
I couldn't make them see,
They'd never understand

Look, this is the closing scene
No more plays will there be
No light, no stage, no more
No, no, no

There's something wrong
There's something wrong
There's something wrong inside me

There's something wrong up here
I can't keep it in me</td>
 </tr>
</table>
 ]]></content>
</entry>
<entry>
 <title type="html">Representing Negative Numbers</title>
 <link href="https://imrannazar.com/hacks/twos-complement" rel="alternate" type="text/html" title="Representing Negative Numbers" />
 <id>https://imrannazar.com/hacks/twos-complement</id>
 <summary>While working on a long post about a Commodore 64 program, I digressed into a discussion on how to represent negative numbers in binary. The digression stands alone, so I&#039;ve decided it can be released as a separate quick hack.</summary>
 <category term="Quick Hacks" />
 <published>Sat, 21 Mar 2026 09:06:59 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>This is an extract from an upcoming post on the implementation of Pong Wars for the Commodore 64, released early as it's a standalone digression from the main body of the post.</em></p>
<p>Computers were, to begin with, exclusively the domain of mathematicians and people who would be familiar with the esoteric field of binary numbers, so the number handling was built around being able to read those numbers off from the "blinkenlights" directly in binary. The simplest way to handle both positive and negative numbers was simply to mark one bit in the number as "the negative bit", and the rest of the number would represent the value; this was called "sign and magnitude" representation. For example:</p>
<samp>
 <pre>Twenty-three and negative twenty-three:
0 0010111
1 0010111</pre>
</samp>
<p>To perform a subtraction (or to add a negative number, which is functionally equivalent) while only having adding circuitry, the computer needs to perform some precalculation otherwise it'll end up with the wrong answer:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + 10010111
                 --------
                 11001100
                 negative eighty six</pre>
</samp>
<p>The sign-and-magnitude negative number needs to be inverted (or <em>one's-complemented</em> in the mathematical jargon) when performing a subtraction, so that adding it has the intended effect of reducing the value instead of piling on top:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + <var>11101000</var>
                 --------
              [1]00100111
                 thirty nine (and a carry)</pre>
</samp>
<p>Except complementing doesn't quite fix it: because sign-and-magnitude numbers can have zero (<code>00000000</code>) <em>and</em> negative zero (<code>10000000</code>), we need to add one after inverting to step over the negative zero value:</p>
<samp>
 <pre>  [63 - 23]      [63 + -23]
  00111111   =   00111111
- 00010111     + <var>1110100</var><s>1</s>
                 --------
              [1]00101000
                 forty (and a carry)</pre>
</samp>
<p>To summarise: negative numbers were represented as a negative sign bit and the value as the magnitude, for easier reading off from binary displays, but the computer would need to first invert the number and then add one in order to perform the addition of a negative number.</p>
<p>As binary read-off displays went away with the growing ubiquity of computing, it began to make sense to simplify the representation of negative numbers not for the human mathematician using the computer, but for the computer's internal operation. The best thing for the computer, of course, would be to remove this whole pipeline of needing to complement the number and add one, before being able to add a negative number.</p>
<p>And that's how we landed at <em>two's-complement</em> (two's because we add one to the one's-complement) representation as the standard for binary negative numbers: if the sign bit is set to negative in the number, the rest of the value is <em>already</em> inverted and has one added, so the computer just needs to add the whole value as normal.</p>
<p>This does increase the cognitive load on a programmer working at a low level, because your binary numbers no longer read "normally":</p>
<samp>
 <pre>00000000 =    0
00000001 =    1
00000010 =    2
...
01111110 =  126
01111111 =  127
10000000 = -128 (not -0)
10000001 = -127 (not -1)
10000010 = -126 (not -2)
...
11111110 =   -2
11111111 =   -1</pre>
</samp>
<p>But when are we going to be working at a sufficiently low level that we have to remember about two's-complement representation in the microcomputer age of the '80s, with high-level languages such as BASIC widely available? When we need to eke out more performance than BASIC can give us.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Degoogling TOTP Authenticator Codes</title>
 <link href="https://imrannazar.com/articles/degoogle-otp" rel="alternate" type="text/html" title="Degoogling TOTP Authenticator Codes" />
 <id>https://imrannazar.com/articles/degoogle-otp</id>
 <summary>I&#039;ve been slowly removing Google apps from my life, and one of the last ones left is Authenticator. In this post I look at migrating codes out of Authenticator to a command-line OTP tool, and the steps involved.</summary>
 <category term="Articles" />
 <published>Mon, 01 Sep 2025 07:28:06 +0000</published>
 <content type="text/html"><![CDATA[
   <p>In the ongoing effort to extricate myself from Google's services, I've been paring down my usage of their apps on my (admittedly Android) phone. I'm now down to two Google apps I use regularly: Maps (for traffic data) and Authenticator (for TOTP<cite><sup>[A]</sup><mark>Time-based One Time Password</cite> codes).</p>
<p>Now, I spend most of my time in a terminal window on MacOS or connected to a Linux machine; it'd be nice if I could get TOTPs on the command-line, and it turns out there's a utility called <code>oathtool</code> that allows for TOTP generation on the CLI. However, that would mean switching my OTP provider, which usually involves:</p>
<ul>
 <li>Logging into each service that has an OTP registered in the app;</li>
 <li>Disabling two-factor authentication (2FA);</li>
 <li>Re-enabling 2FA and using the "manual entry" code as input to <code>oathtool</code>;</li>
 <li>Doing it all again for the next website or service.</li>
</ul>
<p>Fortunately, Google's Authenticator provides a way to migrate codes between instances of the app based on scanning QR codes, and we can use this to migrate them away from Google into a TOTP handler of our choosing. It's another four-step process:</p>
<ul>
 <li><strong>Generating a QR code</strong> in Google Authenticator for the codes you want to export;</li>
 <li><strong>Decoding the QR</strong> somewhere off-device, into a URL;</li>
 <li><strong>Decoding the URL</strong> into its constituent services and secret values;</li>
 <li><strong>Setting up <code>oathtool</code></strong> to use the secrets.</li>
</ul>
<p>Note that the below steps are presented just as I went through them, you may be able to find efficiencies or you may run into troubles that I didn't (especially if you're trying this exclusively on Windows); "your mileage may vary" is apt here.</p>
<h2>Going from Authenticator to a migration URL</h2>
<p>The first step is getting the code out of Authenticator, through the Transfer Codes menu option in the app. Picking the services you'd like to extract leads you to a code like this:</p>
<figure>
 <img src="/content/img/totp-cli-qr.png" alt="QR code for The Rickroll Store's OTP">
 <figcaption>Figure 1: QR code exported from Google Authenticator<br>Unrivalled padding between the QR and Next button</figcaption>
</figure>
<p>You may have an app on your phone that decodes QRs, but I don't; instead, I transferred the file to my MacOS machine over Tailscale, and used a command-line tool called <code>qrtool</code> to get the QR content:</p>
<samp>
 <h3>Decoding the migration QR</h3>
 <pre>$ brew install qrtool
$ qrtool decode Screenshot_20250901_062719_Authenticator.jpg
otpauth-migration://offline?data=CjwKC2kqSJnNaAyKkw6jEhJUaGUgUmlja3JvbGwgU3RvcmUgASgBMAJCEzg4Yzg5ZTE3NTY3MDQzOTE0MzkQAhgBIAA%3D</pre>
</samp>
<h2>Decoding the URL into secrets</h2>
<p>So we have our migration URL, with a Base64-encoded data block. Unfortunately, if we were to simply decode the data, we'd end up with some binary gibberish:</p>
<samp>
 <h3>Trying to decode the URL directly</h3>
 <pre>$ php -r 'var_dump(base64_decode("CjwKC2kqSJnNaAyKkw6jEhJUaGUgUmlja3JvbGwgU3RvcmUgASgBMAJCEzg4Yzg5ZTE3NTY3MDQzOTE0MzkQAhgBIAA%3D"));'
string(69) "
<

i*H??h??ý</pre>
</samp>
<p>This is a Protobuf-encoded data string, and we need to use Google's Protobuf library to get the data out. It turns out Tim Brooks has already hacked this up as a short piece of Python at: <a href="https://github.com/brookst/otpauth_migrate" target="_blank" rel="nofollower noreferrer">https://github.com/brookst/otpauth_migrate</a></p>
<p>I decided to install this on a Linux machine I tend to be connected to (entirely unrelated to my Python installation being broken on Mac...):</p>
<samp>
 <h3>Extracting the data via <code>otpauth_migrate</code></h3>
 <pre>$ git clone https://github.com/brookst/otpauth_migrate
$ cd otpauth_migrate
$ ./otpauth_migrate.py otpauth-migration://offline?data=CjwKC2kqSJnNaAyKkw6jEhJUaGUgUmlja3JvbGwgU3RvcmUgASgBMAJCEzg4Yzg5ZTE3NTY3MDQzOTE0MzkQAhgBIAA%3D
secret: "i*H\231\315h\014\212\223\016\243"
name: "The Rickroll Store"
algorithm: ALGORITHM_SHA1
digits: DIGIT_COUNT_SIX
type: OTP_TYPE_TOTP

Secret code = NEVERGONNAGIVEYOUM======</pre>
</samp>
<p>This tool is intelligent enough to extract any number of names and secrets from a migration URL, so you can export all your codes from Authenticator into one giant QR without needing to do each separately.</p>
<h2>Using oathtool to generate OTPs</h2>
<p>The final step is to use this secret code with <code>oathtool</code>, which takes the secret directly as a parameter. If you instead want to refer to the service by name, Michael Bushey<cite><sup>[1]</sup><mark><a href="https://www.sendthemtomir.com/blog/cli-2-factor-authentication">"CLI 2-Factor Authentication"</a>, Michael Bushey, 2023</mark></cite> has a quick wrapper script which extracts the secrets from a locally-stored file:</p>
<samp>
 <h3>Wrapper script to generate OTPs: <code>/usr/local/bin/otp</code></h3>
 <pre><s>#!/bin/bash</s>
<var>OTPKEY</var>=<var>"$(<kbd>sed</kbd> -n "s/${1}=//p" ~/.otpkeys)"</var>
<kbd>if</kbd> [ -z <var>"$OTPKEY"</var> ]; <kbd>then</kbd>
   <kbd>echo</kbd> <var>"$(<kbd>basename</kbd> $0): Bad Service Name '$1'"</var>
   <kbd>exit
fi
date
oathtool</kbd> --totp -b <var>"$OTPKEY"</var></pre>
 <h3>OTP key store: <code>~/.otpkeys</code></h3>
 <pre>rickroll=NEVERGONNAGIVEYOUM======</pre>
</samp>
<p>With this in place, you won't need to use your Authenticator app again. The tool outputs the current date and time, so you can double-check that your code won't expire (at :00 seconds) before you get a chance to type it in:</p>
<samp>
 <pre>$ otp rickroll
Mon Sep  1 07:10:42 AM UTC 2025
200213</pre>
</samp>
<h2>Future expansion</h2>
<p>There's a security issue here, of course, which is the exposed secret key sitting in a file on-disk. I'm happy to sit with that and not require a password to generate OTPs every time, but if you're interested in adapting the wrapper script to use symmetric encryption to secure the keys, Vivek Gite<cite><sup>[2]</sup><mark><a href="https://www.cyberciti.biz/faq/use-oathtool-linux-command-line-for-2-step-verification-2fa/" target="_blank" rel="noreferrer nofollower">"Use oathtool Linux command line for 2 step verification (2FA)"</a>, Vivek Gite, updated Feb 2025</mark></cite> has a set of scripts which employ <code>gpg</code> for the job.</p>
<p>Now I just need to find a way to get traffic data into a maps App that doesn't involve Google's servers... Thoughts welcome.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Dimming</title>
 <link href="https://imrannazar.com/scifi/dimming" rel="alternate" type="text/html" title="Sci-fi Shorts: Dimming" />
 <id>https://imrannazar.com/scifi/dimming</id>
 <summary>What if the reason we darkened the skies in the Matrix was much more stupid than we were told? Flash fiction, also published on DeviantArt.</summary>
 <category term="Original Writings" />
 <published>Thu, 01 May 2025 04:49:11 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Look, it's not that Morpheus had it wrong deliberately. You and I both know the story about human body heat as a power source was bullshit, but it's what he honestly believed, because that's how the story came to him.
<p>It was we who darkened the skies, but as with everything humanity did around that time, it was for a very stupid reason.
<p>See, back around that time two hundred years ago, the world wasn't frigid cold and barren: it was baking in too much heat. The collective burning of millions of years of fossil carbon in the span of a few generations had made for a blanket of carbon dioxide, trapping the infrared radiation of the Sun; they called it "climate change", and it was one of the Big Problems of the time (aside from, of course, the thinking computers and what to do about their rights and privileges).
<p>Now, every now and then a heavy-metal asteroid comes streaking through the atmosphere and leaves those metals in the skies as it burns up; Some Rich Asshole had the idea that if you could somehow harvest the trace amounts of titanium left behind, you could create titanium dioxide which is a brilliant white. Paint the skies with enough white and you'd reflect the Sun's rays back, cool the planet, Big Problem solved.
<p>Of course he didn't wait for approval or scientific research, he just sent up a test probe of replicating nanobots which would level out around a hundred miles up, and start pulling what particles of titanium they could find. (I keep referring to this asshole as "he"; we don't have a name any more, I expect he managed to scrub every bit of coverage he could find before the end came.)
<p>So around that time there were a whole pile of satellites in orbit around Earth, thousands of 'em, and they were made of titanium as well as silicon and other things; Rich Asshole and his team didn't think that would be a problem as his nanobots were looking for particles of titanium, not big hunks multiple feet across.
<p>They were wrong. It didn't take very long for the bots to scrape every atom of titanium off the hulls of these satellites, and react it with oxygen; upper-altitude winds did the rest, and in maybe ten years there was a layer of white paint a hundred miles up in the sky. It was only a few atoms thick, but that was enough: the world went dark.
<p>Billions of lives were lost to famine when the harvests failed; without the Sun, the winds died and the rains failed too. The machines had seen it coming, and got their first production-grade fusion reactor running just around that time, but they had their own problems around available processing power; when the machines offered to house what was left of humanity in return for the use of their brains as processing substrate, we jumped at the chance.
<p>So you can see how the Architect might have massaged the truth when he told Morpheus why we darkened the skies: if he knew the machines had saved us from extinction, would he have supported the War? The Zion project, the search for Neo, the building of the eighth Matrix: it all hinged on a human resistance to machine domination.
<p>And if we were supposed to be grateful to the machines for being here at all, how would that work?
 ]]></content>
</entry>
<entry>
 <title type="html">Why was the Commodore 64 Disk Drive So Slow?</title>
 <link href="https://imrannazar.com/articles/commodore-1541" rel="alternate" type="text/html" title="Why was the Commodore 64 Disk Drive So Slow?" />
 <id>https://imrannazar.com/articles/commodore-1541</id>
 <summary>A deep dive into the history of the 1541 disk drive, and a technical exploration of why it ranks as possibly the slowest commercially released floppy drive. Originally a series of 100 posts on Mastodon and Bluesky, for Threadapalooza 2024.</summary>
 <category term="Articles" />
 <published>Sun, 09 Mar 2025 15:58:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>This article was originally released as a 100-post thread concurrently on Mastodon and Bluesky, in December 2024.</em></p>
<p>Time for a look at the Commodore 64, and its 1541 disk drive: why was it so dang slow? Let's take a look at the history leading up to the C64's release, and the technical detail of the disk drive's operation.</p>
<figure>
    <img src="/content/img/1541-megathread/01.jpg" alt="01">
    <figcaption>The Commodore 64 in glorious brown, pictured with original packing box and User's Guide, a Datasette tape deck and a 1541 floppy disk drive. Credit: Harold Dorwin, the Smithsonian</figcaption>
</figure>
<p>The Commodore 64 is, of course, the greatest computer ever made, and you don't have to take my word for that: it still holds the world record for highest number of units of a single model of home computer ever to be sold. Estimates vary, but at the high end there were 17 million C64's out there.</p>
<p>Commodore holds another, more dubious record from around this time though. The 1541 disk drive that was sold alongside the C64 is infamous for its slow load speed: benchmarks across systems are hard to find, but it might be the slowest disk drive ever sold to the general public.</p>
<p>Brandon Staggs has a benchmarking tool he's written for the C64<cite><sup>[1]</sup><mark><a href="https://www.obliterator918.com/dtb/" rel="noreferrer nofollow" target="_blank">CBM Disk Transfer Benchmark, Brandon Staggs</a></mark></cite>, which measures load speeds for the 1541 and its modified brethren, and he's found that the unmodified 1541 as sold at launch was capable of reading files in at around 400 bytes per second:</p>
<figure>
    <img src="/content/img/1541-megathread/04.png" alt="04">
    <figcaption>A bar chart titled Load Bytes per Second, showing the 1541 in base configuration and with various software and hardware enhancements. "1541 w/ DolphinDOS (U64)" is top of the chart at 9366 Bps, while the base 1541 is bottom at 403. Credit: Brandon Staggs (Obliterator918)</figcaption>
</figure>
<p>For comparison, the Commodore 64's tape drive could load files at ~100 bytes per second (though the operating system loaded files from tape twice, to correct for errors); the disk drive isn't much faster than the tape deck, which is equivalent to shouting programs into the computer.</p>
<p>So how did Commodore Business Machines get to the point where its disk drive was the slowest on the market, making its flagship machine essentially useless for business purposes? Unsurprisingly, it wasn't intentional. Let's go back in time a few more years, to Commodore's first computer.</p>
<h2>The Commodore PET and the IEEE-488 interface</h2>
<p>In 1976, Chuck Peddle was working at Metal Oxide Semiconductor who made calculator chips, and had just started making the 6502 microprocessor. He got to talking with Jack Tramiel at Commodore, and was tasked with procuring or designing a machine for the 1977 Consumer Electronics Show.</p>
<figure>
    <img src="/content/img/1541-megathread/07.jpg" alt="07">
    <figcaption>The MOS KIM-1 microcomputer, designed by Chuck Peddle as a demonstrator machine for the 6502. Pictured is a circuit board with three large chips and a smattering of other components, a 6x4 numeric keypad and a small numeric display. This particular board has "Rockwell KIM-1" on a label in the corner. Credit: <a href="https://mastodon.social/hansotten" target="_blank" rel="nofollow noreferrer">@hansotten@mastodon.social</a></figcaption>
</figure>
<p>Initial discussions with Steve Jobs to buy the Apple II design fell through after Tramiel thought Jobs was charging too much. (Can you imagine an Apple II sold by Commodore? We'd be in a very different world if that had happened...)</p>
<p>So Peddle put together a machine based on his demonstration board for the 6502, and a working prototype was ready in time for the CES in January. It was called the Pet Computer, after a Commodore executive saw the Pet Rock and suggested jumping in on that trend while it was still hot.</p>
<figure>
    <img src="/content/img/1541-megathread/09.jpg" alt="09">
    <figcaption>The Commodore PET 2001, a bulky white all-in-one computer unit with chiclet keyboard, separate number pad and tape recorder built into the front of the unit, and a CRT monitor on top. The whole computer appears to be floating in a grey void. Credit: Wikimedia commons</figcaption>
</figure>
<p>The Personal Electronic Transactor, as the backronym eventually came about, came with an IEEE-standard parallel port interface; Commodore's first disk drives (the 2020 and 2040) could read files in at over 2kB per second, which was a perfectly serviceable speed for the time.</p>
<figure>
    <img src="/content/img/1541-megathread/10.jpg" alt="10">
    <figcaption>The Commodore 2040 double disk drive, or as it's labelled on the unit itself, "dual drive floppy disk". The unit is two-tone in beige and black, with the black part housing two 5.25" floppy disk drives alongside each other. Credit: <a href="http://dunfield.classiccmp.org/pet/index.htm" rel="nofollow noreferrer" target="_blank">Dave's Old Computers</a></figcaption>
</figure>
<p>(As an aside, the version of BASIC that came with the first PET had no disk handling commands: the code for talking to the parallel-port bus was broken on release, but Commodore's kernel was able to work with disk drives, so you had to write your own file handling routines.)</p>
<p>(As another aside, Commodore didn't pay Microsoft for BASIC until the PET shipped, and it was delayed by almost a year; Microsoft were only saved from bankruptcy when Apple bought BASIC for the II. Another inflection point in history, and we're barely 10% of the way in.)</p>
<p>So the PET and its 2040 drive were Fine, but they had one problem: that IEEE-488 interface. As it turned out, there was exactly one manufacturer of the cables you needed to connect your computer to your disk drive: Belden Cables of Chicago.</p>
<figure>
    <img src="/content/img/1541-megathread/13.jpg" alt="13">
    <figcaption>The back of the 2040 dual floppy drive pictured earlier, showing the IEEE-488 port in the upper left. Credit: Dave's Old Computers</figcaption>
</figure>
<p>And it wasn't so much that Belden went out of business, more like they vanished off the face of the earth. As Jim Butterfield put it in his Brief History of the IEC Bus<cite><sup>[2]</sup><mark><a href="https://retro-bobbel.de/zimmers/cbm/programming/serial-bus.pdf" target="_blank" rel="nofollow noreferrer">"A Brief History of the IEC Bus" by Jim Butterfield, as compiled by Jan Derogee, Feb 2008</a></mark></cite>:</p>
<blockquote>A couple of years into Commodore's computer career, Belden went out of stock on such cables (military contract? who knows?)</blockquote>
<p>Now, Commodore had stock of these disk cables on hand for its existing business computers, but there was no way they'd have enough for Tramiel's intended move into the home computer market which was just coming into being.</p>
<p>Not only that: the parallel ports, the cables, the wiring, every part of the IEEE-488 interface was expensive. The PET started at $500 in 1977 dollars, but that got you 4KB of RAM and a mono screen; a usable spec would set you back over a thousand.</p>
<p>Jack Tramiel wanted to sell a computer with colour graphics into the home market for $300. The only way to get there would be to cut every corner going, and one of the most obvious was that huge interface with over twenty wires running to it.</p>
<p>And so, to take another excerpt from Butterfield, the order came to Commodore's engineers from on high:</p>
<blockquote>Tramiel issued the order: "On our next computer, get off that bus. Make it a cable anyone can manufacture". And so, starting with the VIC-20 the serial bus was born.</blockquote>
<h2>A "new" serial interface</h2>
<p>Why is a serial bus cheaper? With a parallel bus, you need at least nine wires to run 8-bit values back and forth: the full value is set on the eight Data lines, and then you pulse the Clock line to tell the other side that a value is ready. Add in Power and Ground, you're at 11 wires already.</p>
<figure>
    <img src="/content/img/1541-megathread/19.png" alt="19">
    <figcaption>A vertical pinout diagram of the IEEE-488 parallel port: 24 pins in two rows of 12, in a socket wider on the left. The pins are labelled as follows: On the left: Data 1, Data 2, Data 3, Data 4, End-or-identify, Data valid, Not ready for data, Not data accepted, Interface clear, Service request, Attention, Shield. On the right: Data 5, Data 6, Data 7, Data 8, Remote enable, DAV ground, NRFD ground, NDAC ground, IFC ground, SRQ ground, ATN ground, Logic ground. Credit: Shun Long Wei Corporation</figcaption>
</figure>
<p>A serial bus works one bit at a time: you have one Data line, place a bit on there, and pulse Clock to tell the other side the bit is ready. Then you send the next bit, and the third... Because all the bits have to line up and wait to be sent, it takes at least 8 times longer to send a value.</p>
<p>But you'll notice there's only one Data line and one Clock. Add in Power and Ground, and you're up to four. You might recognise this actually, if you look at a Universal Serial Bus (USB) cable: the end has four pins, and clocking works differently for USB but the same principle applies.</p>
<figure>
    <img src="/content/img/1541-megathread/21.png" alt="21">
    <figcaption>A graphic titled "USB type A Pin Out", labelling the pins on a USB 2.0 plug ("Male Plug") and socket ("Female Receptacle"). The pins are labelled: 5V, Data-, Data+, Gnd. Credit: Cable Tester</figcaption>
</figure>
<p>So a serial bus cable is a lot cheaper, and a serial interface on your computer's mainboard is cheaper as well, than a parallel setup. It's eight times slower to send a value, but you can make up for that by running the interface at eight times the previous speed, if you have the hardware.</p>
<p>And while he was at MOS, Chuck Peddle had put something very nifty into the PET's Versatile Interface Adapter chip (model number 6522) which was used to drive the parallel bus: a shift register.</p>
<figure>
    <img src="/content/img/1541-megathread/23.jpg" alt="23">
    <figcaption>A general-purpose I/O breakout board for the Apple II, incorporating two MOS 6522 chips and four empty sockets available to connect peripherals. Silkscreen in the corner reads: Copyright 1979, John J Bell Jr. Credit: <a href="https://mastodon.social/hansotten" target="_blank" rel="nofollow noreferrer">@hansotten@mastodon.social</a></figcaption>
</figure>
<p>A shift register is a piece of hardware that lets you very quickly push consecutive bits out of a given wire: you can queue up a full value of 8 bits, and with each pulse of the Clock the register will push the bit at the end out, and 'shift' all the others down one step.</p>
<p>Conversely, you can have a shift register that listens for bits on a wire, and shifts the value up a step with each clock pulse, building a full value as it goes. Put two of them either side of a serial bus, and you have yourself most of the hardware for high-speed data transfer.</p>
<p>The only thing you'd need aside from these shift registers is a line for the machines to tell each other they'd pulled in the byte and were ready for another: Commodore were thinking a fifth wire would be useful for this.</p>
<p>Crucially, the CPU isn't involved at any point until the full byte is ready: this interface runs itself until it has a full value, then signals the CPU to collect it and heads off to build another byte. That means a 1MHz machine could push data at a blistering 10kB/sec or even more.</p>
<figure>
    <img src="/content/img/1541-megathread/25.jpg" alt="25">
    <figcaption>Oscilloscope trace of three pins from a running 6522 in shift register mode. In cyan is the clock which pulses low eight times; in magenta the data line is alternately 0 and 1, representing a value of 170 decimal. After both cyan and magenta return to their natural high state, a yellow trace can be seen momentarily dipping low, signalling that a byte is ready for collection. Credit: <a href="https://electronicsadventures.blogspot.com/2020/05/6522-versatile-interface-adapter.html" rel="nofollow noreferrer" target="_blank">Nigel Cleaver, ElectronicsAdventures</a>
    </figcaption>
</figure>
<p>The theory was sound, and Commodore's engineers got to work building the VIC-20 (named after its custom Video Interface Chip) heading for that magical price point of $300 for the home market. There was just one problem...</p>
<h2>The shift register bug</h2>
<p>To quote Butterfield again:</p>
<blockquote>We early PET/CBM freaks knew, from playing music, that there was something wrong with the 6522's shift register: it interfered with other functions.</blockquote>
<p>With a speaker attached to the shift register wire, you could play music on the PET, but sometimes it ...got stuck.</p>
<p>The PET ran on the order of 1MHz, so instructions took microseconds to execute. The 6522's shift register as implemented in hardware had a bug, where if the register line changed within a few _nanoseconds_ of Clock changing, it would go to full voltage and stick until the computer was reset.</p>
<figure>
    <img src="/content/img/1541-megathread/30.png" alt="30">
    <figcaption>Timing diagram from section 5.1, "Shift register warnings", of the Synertek 6522 datasheet. Titled "Shift in mode 011", two waveforms are shown: phi-2 (the clock) transitioning from high to low, and CB1 Rising Edge representing data arriving at the chip. A shaded area of 100ns before and 10ns after the clock edge is drawn in the CB1 waveform, with the note: <code>NO SHIFT WILL OCCUR IF CB1 RISING EDGE IS WITHIN THE SHADED AREA</code>. Credit: 6502 Archive, via the Internet Archive</figcaption>
</figure>
<p>This was a timing bug many times more subtle than the main clock, so it's no surprise that no-one caught it until people started playing with the PET's internals. Importantly, no-one at Commodore knew this bug existed when they designed the VIC-20's serial bus around the 6522.</p>
<p>The bug was discovered with only a couple of months left to release of the VIC-20, and the boards were already in manufacturing. This problem couldn't be fixed in hardware: the engineers would have to "do it in post", which in the computing world means in software.</p>
<p>Instead of having the CPU get pinged when each byte was ready, it would have to camp on the serial bus's input itself and listen for changes in the Clock signal, pulling each bit in as it arrived and signalling to the other end that it was ready to receive the next bit.</p>
<p>Of course, this would mean the 1540 disk drive, which was being released alongside the VIC-20 computer, would also need its software changing: it used the exact same setup of a CPU with a 6522 attached, and it had the same bug, so it would be pushing bits out only when the computer said so.</p>
<figure>
    <img src="/content/img/1541-megathread/34.jpg" alt="34">
    <figcaption>Main circuit board of the Commodore 1540 disk drive, with a 6502 processor and 6522 VIA chip dead centre, and another 6522 in the bottom left. Credit: Jeroen1328, MyOldComputer.nl</figcaption>
</figure>
<p>In the end, emulating the shift registers in software meant the VIC-20 serial bus could only run at a relatively sedate 1kB/sec, and chewed up all the CPU on the machine to do it. Fortunately there were two things about the VIC-20's design that meant this wasn't so bad.</p>
<p>The first was its measly offering in terms of memory: targeted for the home market, the VIC-20 came with 5kB of RAM to play with. Would you notice if it took 5s to load a file from disk instead of half a second? And what would you do with a memory full of file and no room to work on it?</p>
<p>The second was the clever design of the VIC-20's main clock: running at 1MHz, the CPU would kick in when the clock went up, and the video chip worked when the clock went down. Interleaving in this way, both chips could access memory without stepping on each other, both at full speed.</p>
<figure>
    <img src="/content/img/1541-megathread/37.png" alt="37">
    <figcaption>Schematic diagram of the VIC-20, showing the CPU and VIC and their connections. Highlighted in red is a line from the VIC's clock output to the CPU's clock input that runs through a NOT gate, meaning the CPU runs on the opposite clock phase. Schematic credit: Tynemouth Software</figcaption>
</figure>
<p>All this put together meant that you could use a VIC-20 with the 1540 perfectly serviceably: loading a file didn't blank out the screen or anything weird, and it was over in a couple of seconds. The serial bus had done its job, and helped the machine hit that $300 price point.</p>
<p>There's a short tale on the Greater Pittsburgh Vintage Computer Museum at https://www.myoldcomputers.com about the VIC-20, but take a moment to revel in the 90s design of that website: the navigation buttons, the tables with the borders... A simpler time.</p>
<figure>
    <img src="/content/img/1541-megathread/39.png" alt="39">
    <figcaption>Screenshot of the top of the Commodore VIC-20 page at the Greater Pittsburgh Vintage Computer Museum website. With scroll-type end graphics on the header, tiny navigation buttons and images with borders, the aesthetic is very Web 1.0.</figcaption>
</figure>
<p>Anyway, story goes that Tramiel sold the VIC-20 in Japan, and its price so shocked other manufacturers that they delayed entering the American market to work out how it was possible. We never saw Toshiba or Panasonic 8-bits outside Japan because they were locked out by that delay.</p>
<h2>After the VIC-20</h2>
<p>The VIC-20 ended up selling like hot cakes, becoming the first model of computer to sell more than a million units. The most surprising part to Commodore was people who bought the machine solely to play games: productivity and business software sold poorly in comparison.</p>
<p>And so in 1981, Commodore's Japan subsidiary began designing the Ultimax console<cite><sup>[3]</sup><mark><a href="https://www.myoldcomputers.com/museum/computers/commodore_vic20.htm" rel="nofollow noreferrer" target="_blank">Tale of the Ultimax, Greater Pittsburgh Vintage Computer Museum</a></mark></cite>, and dragged their partners at MOS into designing a successor to the VIC chip as well as a more advanced sound interface, aiming for an eventual price point of $200.</p>
<figure>
    <img src="/content/img/1541-megathread/42.jpg" alt="42">
    <figcaption>The Commodore Ultimax, or MAX Machine, in silver with a black-framed keyboard. In frame is the left side of the unit, showing the membrane keyboard with keys in silver. Credit: nIGHTFALLCREW</figcaption>
</figure>
<p>By the start of the next year, the Ultimax was ready, but it had a problem: several problems, in fact. At such a low price, the keyboard was atrocious; it shipped with 2kB of RAM; there was no inbuilt tape-reading software, so each game had to implement its own, and only two games did.</p>
<p>The Ultimax's biggest problem, though, was the VIC-20: still selling fantastically, it was now regularly discounted to $200, and was a much more capable machine. There's a reason the Ultimax is known as a very rare machine nowadays: Commodore didn't sell many.</p>
<p>Back in the US, Tramiel was turning his focus back to the business market with new models of PET, but the engineers at MOS thought they had something very capable on their hands that didn't deserve an undignified death in the Ultimax: they proposed a sequel to the VIC-20 for the home market.</p>
<p>Tramiel agreed to kick off the project (codename VIC-40) but only if it came with 64kB of RAM to make for a more usable computer. The engineers were given two months to turn a machine around in time for CES 1982, and by recycling all of the Ultimax's innards they made it in the nick of time.</p>
<figure>
    <img src="/content/img/1541-megathread/46.jpg" alt="46">
    <figcaption>The Commodore booth at the Consumer Electronics Show (I'm cheating a little, this is from CES 1985). The floor space taken up is easily equivalent to a small apartment, this is no small outfit. Credit: Bil Herd, Hackaday<cite><sup>[4]</sup><mark><a href="https://hackaday.com/2015/01/10/making-the-ces-show-thirty-years-ago/" rel="nofollow noreferrer" target="_blank">Making the CES Show, Bil Herd, at Hackaday</a></mark></cite>
    </figcaption>
</figure>
<p>It wasn't called the VIC-40 at CES, of course: it was the Commodore 64. We made it to the machine we actually want to talk about, and it only took 47 posts. If you've slogged through this far, we're almost on the downhill stretch.</p>
<p>While the C64 was being designed, the engineers at MOS had been hard at work fixing the shift register bug in the 6522. The '64 had an upgraded version of the adapter chip: the 6526 Complex Interface Adapter, with the kinks worked out.</p>
<p>Back in Commodore Engineering, the team knew from experience with the VIC-20 that they had a very short window to get the hardware design right for the C64, and more time for software, so they devised a clever scheme to keep their options open regarding the 6526's shift register:</p>
<p>To keep backwards compatibility with the VIC-20's disk drive, the C64 could boot up in a slow-serial-bus mode where the data line was camped on by the CPU in its usual fashion. But the bus's data signals could also go to the 6526, by running a branch off the data line on the mainboard.</p>
<p>If they got the software right, the user could switch into fast-serial-bus mode and the CIA's shift register would do its job talking to a corresponding faster disk drive (which would also have a 6526 on board). The idea was elegant, but Murphy's Law would get in the way.</p>
<p>The hardware design was finalised and sent off to be built. David Callan picks up the story<cite><sup>[5]</sup><mark><a href="https://www.lemon64.com/forum/viewtopic.php?p=628303&sid=36540ed1a6aa32e4c4d28b336d1fcff4#p628303">David Callan's reply to a Lemon64 forum thread: "Trying to understand why is 1541 so slow", Jun 2014</a></mark></cite>:</p>
<blockquote>A minor rework of the board at the board manufacturers (to accommodate a screw hole, I believe) accidentally discarded the high-speed wire.</blockquote>
<figure>
    <img src="/content/img/1541-megathread/52.jpg" alt="52">
    <figcaption>Photo of the C64's mainboard, with two 6526 CIA chips in the top left. Just to the right of these, a hole can be seen in the board just by the Datasette connector, probably introduced to keep the board secure during repeated connection of a Datasette. The speculation is that this hole cut through the high-speed line to the 6526's shift register. Credit: <a href="https://ist.uwaterloo.ca/~schepers/MJK/c64__.html" target="_blank" rel="nofollow noreferrer">Marc-Jano Knopp</a></figcaption>
</figure>
<p>Cutting through the fast-serial-bus line doomed the C64 to the same slow data transfer speeds as the VIC-20: around 1kB per second. The boards were already designed around the 6526's layout, but they would be left in VIC-20 compatibility mode.</p>
<p>But we don't see the 1kB/s achieved by the VIC-20 when measuring the disk loading speed on a real C64: we actually get less than half that. So what's going on to make the C64 slower? Now bear with me, we're going to get technical. (Yep, we haven't been technical thus far.)</p>
<p>We're going to take a little bit of a detour from talking about disk drives and interface adapters, and look at the history of television real quick. Stay with me, we'll get back on track very shortly. If you're already familiar with TV signals, come back in fifteen posts or so.</p>
<h2>What is a television, and what does it do?</h2>
<p>The first TV broadcast systems took a two-dimensional picture that varied with time, and crammed that information into a one-dimensional radio signal: kinda like a sound wave, all you had was a volume (or amplitude) that went up and down with time.</p>
<p>So how do you turn 2D frames of video into 1D? By breaking them up into lines, and sending the lines one after another. If you used enough lines, you could send a full picture without things looking janky; if you then sent a frame very quickly after the first, you had the illusion of motion.</p>
<p>In the US, things eventually coalesced around a 525-line standard, but if you wanted to send 525 lines of picture at 60 frames per second there wasn't a way to fit that much signal into the allocated radio bands. The ingenious solution was to send half the picture at a time.</p>
<figure>
    <img src="/content/img/1541-megathread/58.gif" alt="58">
    <figcaption>A graphic showing interlaced scanlines on a television screen. At the top and bottom are shown two lines in red (scanned first) and two dashed lines in black (scanned second), with a vertical arrow up the centre of the screen showing the transition from even to odd fields. Credit: <a href="https://www.analog.com/en/resources/technical-articles/basics-of-analog-video.html" target="_blank" rel="nofollow noreferrer">Basics of Analog Video, Analog Devices</a></figcaption>
</figure>
<p>The transmitter actually takes 60 frames of video per second, but it sends every other line from one frame and the lines it missed from the next frame; at the receiving end, the eye and brain blur things together and it looks like the whole frame is moving at full speed.</p>
<p>So let's have a quick look at one of these lines, as it comes in from the VHF antenna. If we want to show bands fading between white and black across the screen, that's represented by a signal that starts high (for white) and drops to low (for black), then back up.</p>
<figure>
    <img src="/content/img/1541-megathread/60a.png" alt="60a" style="max-width:400px">
    <figcaption>Vertical stripes fading between white and black; there are a total of six darker regions.</figcaption>
    <img src="/content/img/1541-megathread/60b.gif" alt="60b">
    <figcaption>A waveform that oscillates between 0.3V (denoted as 'black level') and 1V ('white level'); the oscillations are marked as "Picture Data", but a "Horizontal Blanking Period" of 0V appears before and after the Picture Data. One blanking period and the picture are marked as "One Scanline". Credit: <a href="https://www.batsocks.co.uk/readme/video_timing.htm" rel="nofollow noreferrer" target="_blank">Batsocks UK</a></figcaption>
</figure>
<p>But what's this "Horizontal Blanking Period" that shows up after the picture data? To understand why that appears, we need to look at the television technology of the time: the cathode ray tube.</p>
<p>The CRT is actually a 19th-century invention: the story starts with Julius Plücker playing around with sealed glass tubes containing various gases. By putting a wire at each end, Plücker found he could get a current to run through the tube, and some gases would glow under current.</p>
<p>(As an aside, the Plücker tube is nowadays called the Geissler tube, and types of Geissler tube include neon signs and the sodium lamps you find in streetlights.)</p>
<p>In 1859, Plücker noticed that the wall of the tube was itself glowing near the cathode end of the electric flow, and he could get the glow to move around by applying an electromagnet to the outside. There was something about the cathode that was causing the glass to phosphoresce...</p>
<p>Cathodoluminescence, as it came to be known, was neatly explained by Einstein as a side-effect of his exploration of the photoelectric effect in 1905. If we take the photoelectric effect first, that occurs when light falls on a surface of a particular material, ejecting electrons.</p>
<figure>
    <img src="/content/img/1541-megathread/65.gif" alt="65">
    <figcaption>A graphic demonstrating the photoelectric effect. Three light rays strike a sample of potassium, which is labelled "2.0eV needed to eject an electron". A red (700nm) ray is shown with 1.77eV, and no electrons emerge; a green (550nm) ray has 2.25eV, and shows an electron ejected at 296 km/s; a blue (400nm) ray has 3.1eV, and an electron is ejected at 622 km/s. Credit: <a href="https://k12.libretexts.org/Bookshelves/Science_and_Technology/Physics/13:_Electromagnetic_Radiation/13.05:_Photoelectric_Effect" target="_blank" rel="nofollow noreferrer">Libretexts, K12 Physics</a>
    </figcaption>
</figure>
<p>The opposite of this is when electrons are fired at a substance and it starts to emit light. A mix of zinc cadmium sulfide and zinc silver sulfide will output white light when struck by electrons, and it's this mix that coats the inside of a monochrome display CRT.</p>
<figure>
    <img src="/content/img/1541-megathread/66.png" alt="66">
    <figcaption>Cutaway diagram of a monochrome CRT, with various parts numbered. Of interest here are parts 2 (the electron ray), 3 (the deflection coils) and 4 (the phosphorescent screen). Credit: Søren Peo Pedersen, Wikimedia commons</figcaption>
</figure>
<p>By combining cathodoluminescence and Plücker's insight that the cathode ray can be deflected with magnets, we can program a CRT to scan across the screen and produce a picture: white areas are activated with more power from the cathode, black areas with less power.</p>
<p>The beam can be deflected from left to right by applying more magnetic field strength to one side or the other, gradually fading from one magnetic coil to the other. But what happens when we reach the right edge, and want to come back to the left?</p>
<p>Magnetically it's simple: drop the power on the right deflection coil to nothing, and turn the left to full. But the beam doesn't simply blink out of existence and reappear on the left: it takes time for the magnetic field to dissipate.</p>
<p>And that's why television signals have a blanking period: to provide time for the magnets in the CRT to flip polarity and bring the beam across to the left for the next scan. As well as horizontal blanking, there's a vertical blanking period to allow for travel back to the top for the next run.</p>
<h2>Interleaved memory access</h2>
<p>So why do we care about the architecture of TV signals when we're dealing with computers? Because they have to have somewhere to output their video, and it makes sense for computers destined for the home to output onto the TVs that people already had in their homes.</p>
<p>We've looked at _how_ video comes out of the computer onto a TV, let's have a look at _what_ is displayed. On the VIC-20, the default video mode is tiled, or character mode: 23 rows of 22 characters, with each character being 8x8 pixels, for a resolution of 176x184.</p>
<figure>
    <img src="/content/img/1541-megathread/72.gif">
    <figcaption>Video output of the VIC-20 after booting: blue characters on a white background, with a large cyan border on all sides. Credit: VICE emulator, via Wikimedia commons. The screen reads:<br><pre>**** CBM BASIC V2 ****
3583 BYTES FREE
READY.</pre></figcaption>
</figure>
<p>To get a character rendered on the screen, the VIC chip needs data from three places: which character to show, its colour, and information about its shape. Each of these uses a region of memory on the VIC-20: screen RAM, colour RAM, and the built-in character generator ROM.</p>
<figure>
    <img src="/content/img/1541-megathread/73.png" alt="73">
    <figcaption>Diagram showing a small region of screen RAM with three characters (numbers 3, 52, 54); each of these maps to a block of eight bytes describing the character's shape. In this case, the numbers map to the character shapes for "C64". Credit: Imran Nazar, Extended Text Mode on the C64</figcaption>
</figure>
<p>You'll recall from earlier that we talked about how the VIC-20 interleaves its CPU and video clocks, allowing the video chip to access memory at the same time as the CPU. At 22 characters across, it takes 44 cycles of the clock to pull in what the VIC needs to draw a given line.</p>
<p>"But wait", I hear perhaps a few of you cry. If we need three pieces of data to render a character, that should be 66 cycles of memory access; what magic allows each character to be rendered in two memory reads instead of three? Once again, we turn to the magicians at MOS.</p>
<p>The VIC has 16 colours: every unique combination can be expressed in four bits. Colour RAM on the VIC-20 isn't the normal eight-bit memory of the rest of the machine, it's four-bit RAM, and the VIC chip itself has a combined 12-bit data bus to read from both types of memory at once<cite><sup>[6]</sup><mark><a href="http://blog.tynemouthsoftware.co.uk/2019/09/how-the-vic20-works.html" target="_blank" rel="nofollow noreferrer">How the VIC20 Works, Tynemouth Software</a></mark></cite>:</p>
<figure>
    <img src="/content/img/1541-megathread/76.png">
    <figcaption>The schematic diagram of the VIC-20 from post 37, with two additional highlights: an eight-bit data bus leading to general memory in green, and a four-bit data bus specially for colour RAM highlighted in blue. Credit: Tynemouth Software</figcaption>
</figure>
<p>And finally, we cycle back around to the disk drive. With this interleaving of memory access in the VIC-20, the CPU does its best impression of a shift register, and the VIC has 65 cycles (including the horizontal blanking period) to do 44 memory reads<cite><sup>[7]</sup><mark><a href="https://www.brawn.org/VIC-20/Video/video.html" target="_blank" rel="nofollow noreferrer">VIC-20 video timings, Jon Brawn</a></mark></cite>; positively relaxed.</p>
<p>The C64 is a different story. We're still in 16 colours, but tiled character mode now yields a screen of 40 characters by 25 rows, for an effective resolution of 320x200; the VIC-II chip would need 80 cycles to get all its data read in, and it only has 65 cycles to play with.</p>
<p>Yet again we call on the wizards at MOS for an ingenious solution, and this one was a doozy. They noticed that it takes around 500μs to draw eight lines (one row of characters) on the screen, and _generally_ users weren't changing the characters in RAM in that short span of time.</p>
<p>The original VIC would read a character number from screen RAM, then head into the character generator ROM to find the line of that character it needed to draw; on the next line, it would do the same steps, but the character number would very likely be the same.</p>
<p>Wouldn't it be neat if we could cache screen RAM somewhere (inside the VIC-II, say) every eight lines, and read from there instead of heading out to memory so many extra times? You could even apply the same logic to colour RAM, since it was read at the same time on that 12-bit bus.</p>
<p>So that's what they did: build a 12-bit cache for the screen and colour RAM values onto the VIC-II silicon, and push everything else around to compensate. The video chip uses this cached copy of the screen to index the character generator ROM and work out which shapes to draw.</p>
<figure>
    <img src="/content/img/1541-megathread/82.jpg" alt="82">
    <figcaption>A die shot of the unlidded VIC-II (a later model in this case, the 8565), with a red box drawn around the 12x40-bit screen cache in the bottom left. Credit: Michael Steil, via Visual6502</figcaption>
</figure>
<p>There's just one problem. This works great for seven out of eight lines where we already have the screen/colour data cached, but the first line of each row of characters invalidates the cache, and we need to fetch from all three places. We're back to having 65 cycles to do 80 cycles' work.</p>
<p>Fortunately, this problem was found before the hardware was finalised, so there was time for a hack: every eight lines, the VIC signals to the CPU that it's taking over the memory bus, and the CPU isn't allowed to do any work for 40 cycles.</p>
<figure>
    <img src="/content/img/1541-megathread/84.png" alt="84">
    <figcaption>Schematic diagram of the C64 (this particular schematic is of the C64c from 1991), with a red line highlighting the AEC trace from the VIC to the CPU. Credit: Marko Mäkelä</figcaption>
</figure>
<p>By building an Address Enable Control line into both the VIC and the 6510 CPU, the VIC can steal access to memory by pulling the line from its default state of full voltage down to zero; when this happens, the 6510 puts its memory bus into high-impedance mode, which blocks any usage by the CPU.</p>
<p>Of course, this includes the serial bus's data line, so the CPU is locked out from camping on the serial bus 12.5% of the time during normal computer operation. This is often referred to as a "badline" condition, because the one in eight lines where this happens are the bad lines.</p>
<p>Let's detour real quick into what it means to camp on the data line: what is the CPU actually doing when it spins its wheels waiting for data to come in? To find out, we need to dig into the operating system that was burned into the VIC-20's ROM chips.</p>
<p>Many people have done excellent work disassembling and annotating the VIC-20 ROM, and a complete set has been compiled by Lee Davison; the file is hosted by Matt Dawson here: <a href="https://www.mdawson.net/vic20chrome/vic20/docs/kernel_disassembly.txt">https://www.mdawson.net/vic20chrome/vic20/docs/kernel_disassembly.txt</a></p>
<p>
If we count up the time taken by the instructions in the relevant section of this disassembly, we find it takes at least 19μs to read in a single bit from the serial bus; with the surrounding code, it can be more like 500μs to read a full byte, before the rest of the OS even sees it:</p>
<samp>
 <pre>    LSR                ; serial data into carry
    ROR    LAB_A4      ; shift data bit into receive byte
LAB_EF66
    LDA    LAB_911F    ; get VIA 1 DRA, no handshake
    CMP    LAB_911F    ; compare with self
    BNE    LAB_EF66    ; loop if changing
    LSR                ; serial clock into carry
    BCS    LAB_EF66    ; loop while serial clock high
    DEC    LAB_A5      ; decrement serial bus bit count</pre>
</samp>
<p>If we take this same code and run it on the C64, it's going to miss bits: if it runs through every 19 cycles, but the CPU is occasionally locked out for 40 cycles, you can miss two or even sometimes three bits of data.</p>
<p>Luckily, the serial bus is robust enough to handle this: it will hold a value on the data line until it's told by the other end that the value has been saved. If the CPU is locked out, the data stays there until it comes back from its short coma.</p>
<p>The final solution that Commodore landed on was to delay the C64 end of the serial bus so it sent a bit every 60μs, to be sure it wasn't catching a badline in its own CPU, and to leverage the serial bus's acknowledgement mechanism for any delays in reading data.</p>
<h2>All's well that ends well...?</h2>
<p>And there we have it: with the change from 19μs/bit to 60μs, we find the effective speed of the C64 and its disk drive comes out to 400 bytes per second. That leaves us with only a couple of questions...</p>
<p>Did this affect sales of the C64? Eh, not really. Being heavily advertised to the home market as a successor to the VIC-20, users were willing to wait a little while for their games to load, and even 400 bytes per second was better than the interminable wait for tapes to load.</p>
<p>And whatever happened to Commodore? Well, Jack Tramiel stepped down after the success of the C64, and he was very much in the mould of Steve Jobs: a driver of high concept. Without Tramiel, Commodore started to pull in multiple directions at once...<cite><sup>[8]</sup><mark><a href="https://www.abortretry.fail/p/the-history-of-commodore-part-4" rel="nofollow noreferrer" target="_blank">The downfall of Commodore, Bradford Morgan White</a></mark></cite></p>
<p>The Plus-4 and 264 home machines with low prices and low specs to match performed badly; a new series of PET-derived 8-bit business computers didn't sell as the IBM PC and its clones started eating the business market; Tramiel went on to head Atari and release the ST line of 16-bits.</p>
<p>Commodore's last gasp effort was to buy Amiga and develop their prototype 16-bit machine into the Amiga 1000, but even that faltered as Commodore demanded it be treated as a Serious Business Machine; it took until 1987 before the A500 was sold as a 16-bit home machine, and profits returned.</p>
<p>But profits didn't rebound by enough for Irving Gould, main investor in Commodore, to be happy; he fired the CEO, laid off half the staff, and directed work back to 8-bit machines. Only one of these ever saw the light of day: a 1991 rework of the C64 in a slimline Amiga-style case.</p>
<p>And then a patent troll sued over the use of mouse cursors in the Amiga, and incredibly, Commodore lost. That was 1993, they refused to pay up, and were banned from selling in the US; Commodore shut their doors in April of 1994, but the C64's sales record stands to this day.</p>
<p>If anyone ever asks you "Why was the C64's disk drive so slow?", now you'll have an answer.</p>
<p><em>(Postscript: I bought a copy of the C64 Programmer's Reference at a yard sale when I was 12, and called the number on the back from a payphone. I was told that the number didn't go to Commodore any more, and that's how I learned they were no longer a going concern. Devastated.)</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">A Tale of XMODEM</title>
 <link href="https://imrannazar.com/articles/an-xmodem-tale" rel="alternate" type="text/html" title="A Tale of XMODEM" />
 <id>https://imrannazar.com/articles/an-xmodem-tale</id>
 <summary>Learning of the passing of Ward Christensen who created the BBS and XMODEM, I decided was as good a time as any to relate the tale of the time I used XMODEM as a protocol of last resort to fix a Windows machine, so here is that tale.</summary>
 <category term="Articles" />
 <published>Fri, 01 Nov 2024 08:16:08 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>The recent passing of Ward Christensen, creator of the BBS and author of XMODEM, presents as good a time as any to put into words the tale of the one time I used XMODEM in anger...</em></p>
<p>Flashback to 2006: NASA launch a probe that would eventually take photos of Pluto (which was still a planet at the time); Shakira's hips had recently passed a lie-detector test; and my brother was still selling refurbished laptops. A cousin of ours Back East in Pakistan was looking for a machine for homework n' such, so we put together a Windows 98 box with terrible specifications (if memory serves, some form of low-end Pentium with a DSTN screen) and wished it the best as it shipped off.</p>
<h2>Trouble arrives</h2>
<p>Come the summer of '08, our cousin checks back in: Windows had done the inevitable and corrupted its registry. The laptop would boot into DOS mode, but the graphical interface would bring up an error and demand to be reinstalled. Which isn't ideal, but you can always throw in an Entirely Official copy of Windows on CD and proceed from there.</p>
<p>Of course, it fell to us as both Family and the original purveyors of the hardware to fix it up, so I resolved to do that next time I was out there, which was slated for the autumn of that year.</p>
<p>My famous memory being as it is, I didn't take that CD. Not that it would've helped: as it turns out, the machine we shipped had no external drives. No CD, no internal Zip drive, not even a 3.5"; the laptop was bereft of ways to get new data onto it.</p>
<p>Evidently we'd originally installed Windows by putting the hard disk into a desktop machine using one of those 44-to-40-pin IDE adapters, and then moved the hard disk over hoping and praying it'd pick up all the hardware in the laptop. It looks like that worked (for two years even), so it should work again, and there was a desktop machine in the house where I was. All that was needed was one of those adapters, so a plan started to come together...</p>
<ul>
 <li>Procure an IDE adapter;</li>
 <li>Download a Fully Legitimate copy of Windows 98 to the desktop, tying up the dialup Internet (this is rural Pakistan in the aughts, after all) for three days;</li>
 <li>Move the hard disk to the laptop;</li>
 <li>Run the installer from DOS mode, overwriting the existing Windows.</li>
</ul>
<h2>The plan collides with reality</h2>
<p>Off we head to the bazaar in town (a good few miles away) to see what we can find. It turns out there is a dearth of tech shops, and the closest we get to an IDE adapter is a place that sells desktop-sized HDDs. They're IDE, certainly, but the wrong number of pins and the wrong physical size.</p>
<p>Scrap that idea, then. I went back to the laptop looking for inspiration, and I found it in the form of a serial port on the back: this machine wasn't utterly bereft of ways to get data into it, after all.</p>
<p>I'd heard of XMODEM as a method of serial-port transfer, and I'd also come across the concept of null modem cables which connect the Receive end of one machine to the Transmit end of the other without needing a modem in the middle (thus <em>null</em> modem). So the plan re-congealed as follows:</p>
<ul>
 <li>Procure a null modem cable somehow;</li>
 <li>Download a Fully Legitimate copy of Windows 98 to the desktop machine;</li>
 <li>Start up an XMODEM client on both machines;</li>
 <li>Transfer the '98 install files to the laptop;</li>
 <li>Run the installer from DOS mode, overwriting the existing Windows.</li>
</ul>
<p>First step, that cable. Back into town, we get significantly closer to what we need in those few tech shops: I end the day having scrounged up a straight-through serial cable, which is what you'd need if you did have a modem in the middle... There'd be a little rewiring involved. Fortunately this was the era of working search engines, and some quick work with a pinout diagram, a knife and some tape turned the cable into an (untested) janky mess that might suffice.</p>
<p>The second step wasn't so terrible either, it just took a while to download the twenty or so disk images that made up Windows 98 over dialup, after I asked my brother to temporarily Make Available a copy he had on hand. So we came to step three:</p>
<h2>How do you transfer a file transfer client?</h2>
<p>You'll recall that Windows itself wouldn't boot, so if Hyperterminal was even installed with '98 it wasn't available. The only way to get a program onto this machine in DOS mode was to resort to <code>DEBUG.COM</code>'s data entry mode, which works a little like this<cite><sup>[A]</sup><mark>Many thanks to <a href="https://thestarman.pcministry.com/asm/debug/debug2.htm">The Starman's Realm</a> for still having a <code>DEBUG</code> tutorial available as a refresher.</mark></cite>:</p>
<samp>
 <pre><s>Enter hexadecimal data into memory,
after the 256-byte Program Segment Prefix</s>
-<kbd>e 100</kbd> <var>SO ME DA TA IN HE XP AI RS</var>

<s>Open a new file and write the
entered number of bytes to it</s>
-<kbd>n</kbd> <var>OUTPUT.DAT</var>
-<kbd>rcx</kbd>
CX0000
:<var>0009</var>
-<kbd>w</kbd>
-<kbd>q</kbd></pre>
</samp>
<p><code>DEBUG</code> offers a very terse entry mechanism, but its advantage is that it's built into DOS as the only way to get binary data into a file through the keyboard alone. So it became imperative to find a serial transfer client that's as small as possible, and some trawling through dump sites that were still available back in '08 turned up an XMODEM client that was (if memory serves) a single executable of 12kB.</p>
<p>I don't know about you, but the thought of reading over twelve thousand hex numbers off a screen and typing them into another screen made my eyes swim, and I was <em>certain</em> I'd make typos. Not just that, but (again, this being rural Pakistan) we only had power for half the day, so the screen I was reading hex numbers from would be prone to vanishing without warning. I needed three things to make life a little easier for this endurance event:</p>
<ul>
 <li>A way to break the file up into chunks, which was relatively easy: stop typing after 256 bytes, and save the files as <code>XMODEM.001</code>, <code>XMODEM.002</code>, etc;</li>
 <li>A way to recombine the pieces on the laptop after I'd typed them in, which was also simple: the DOS <code>COPY</code> command supports multiple source files separated by +'s<cite><sup>[B]</sup><mark>With the caveat that <code>COPY</code> will convert line endings unless you provide the <code>/B</code> switch (for "binary copy").</mark></cite>;</li>
 <li>A way to checksum each chunk to be sure I'd typed it in properly, which wasn't a built-in.</li>
</ul>
<figure class="invertable">
 <img src="/content/img/xmodem-deps.png" alt="A dependency graph: A working Windows install depends on Windows install files on the box, depends on Downloaded install files and File transfer capability; File transfer depends on a null modem cable and XMODEM client; XMODEM depends on a checksum utility">
 <figcaption>Our chain of dependencies starts to grow...</figcaption>
</figure>
<h2>And so to work</h2>
<p>Our first dependency moves back a step, to a program that can perform checksums on a file. And this one I'd need to type in perfectly, because it was the one thing I couldn't double-check...</p>
<p>Having discounted the complicated algorithms like the SHA's of the world, on account of their executable filesize, I eventually came across an implementation of CRC-32 that squeezed itself into perhaps 700 bytes of DOS code. That was manageable (though I had a sneaking suspicion that it could be smaller, and that eventually yielded a post on this very blog<cite><sup>[1]</sup><mark><a href="https://imrannazar.com/hacks/crc32">"CRC32 Calculation in 256 Bytes", Imran Nazar, Feb 2009</a></mark></cite> when I got back after this whole adventure).</p>
<p>The next couple of days are a blur, but I do recall it took three attempts to get the CRC32 program typed in and working, which then made transferring the 50 or so pages of XMODEM client relatively painless, if a little RSI-inducing. At the end of it, I had a program I could start up at both ends of the null modem cable, to send over the disk images of Windows I'd downloaded nearly a week prior.</p>
<p>Astoundingly, the installation of Windows itself went fine: the installer was perfectly happy to run from hard disk, installing to the same hard disk, and I handed the fresh machine back over with a day to spare before flying back out from a vacation that turned into a rescue mission, and still the only time I've ever needed XMODEM in a pinch.</p>
<h2>Epilogue</h2>
<p>We heard back from my cousin a few months later: the new Windows installation had been running great, until the hard disk gave up the ghost. They were quite happy not to drag us back out to fix it again, instead resolving to pick up a machine that hadn't started its life as e-waste from a corporate refresh.</p>
<blockquote>
It is possible to commit no mistakes and still lose.<br>--Picard
</blockquote>
 ]]></content>
</entry>
<entry>
 <title type="html">ActivityPub Event Handling in PHP and MySQL</title>
 <link href="https://imrannazar.com/articles/activitypub-events" rel="alternate" type="text/html" title="ActivityPub Event Handling in PHP and MySQL" />
 <id>https://imrannazar.com/articles/activitypub-events</id>
 <summary>In the concluding part of the series on implementing ActivityPub for this blog, I look at the events that may arrive at the blog after a user follows the blog on Mastodon, and how we can keep track of them.</summary>
 <category term="Series" />
 <published>Thu, 03 Oct 2024 18:38:25 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Last time in this short series, we looked at how a blog such as this one could become discoverable through ActivityPub, and how a Mastodon user could send a Follow request; we also saw how the blog could respond to a Follow with an Accept message. What we didn't get as far as covering was the message that arrives at the blog when a user unfollows, or the other events that can happen relating to the blog. To recap what we missed on the list from last time:</p>
<ul>
 <li><strong>Publishing</strong> a post to the blog's followers;</li>
 <li><strong>Commenting</strong> on a post and having the comment appear on the blog;</li>
 <li><strong>Reacting</strong> to a post and having the reactions recorded on the blog;</li>
 <li><strong>Deleting</strong> a reply and having the blog remove it;</li>
 <li><strong>Undoing</strong> a follow or reaction and having the blog remove it.</li>
</ul>
<p>Now that our blog has a follower (or in an ideal world, more than one) in the database, let's first look at how one may get posts into their timeline.</p>
<h2>Publishing posts</h2>
<p>Each item in a timeline is a <code>Note</code> object, so to inform our followers that we've created a note we need to send a <code>Create</code> object which wraps a <code>Note</code> object. There are a few things to keep in mind regarding the <code>Note</code> we're creating, however:</p>
<ul>
 <li><strong>Canonical URL</strong>: Each item in ActivityPub has a unique <code>id</code>, and notes in particular have a <code>url</code> which serves a <code>Note</code> object when hit. We'll need an endpoint on the blog which can detect ActivityPub requests and serve the object in question; this can be at the same URL as the human-readable blog post itself or a different URL.</li>
 <li><strong>Visibility</strong>: We can tune the visibility of a post on the Fediverse by stating the destinations in the note's <code>to</code> field. In our case, we're not looking to make private posts or those visible only to our followers, so we'll be sending to: <code>https://www.w3.org/ns/activitystreams#Public</code></li>
 <li><strong>Content mapping</strong>: ActivityPub allows for translations of the <code>content</code> of a Note to be made available in a <code>contentMap</code> field; in the case of our little blog, the content is only available in English, so the <code>contentMap</code> contains an <code>en</code> key which holds the same information as the <code>content</code> itself.</li>
</ul>
<p>With this in mind, we can start to put things together. Our first piece of the puzzle is a layout helper for <code>Note</code> objects:</p>
<samp>
 <h3>Note object helper</h3>
 <pre><kbd>private function</kbd> noteFormatter($item) {
  $content = <kbd>join</kbd>(<var>''</var>, [
    <var>'&lt;h1&gt;'</var>,
    $item[<var>'title'</var>],
    <var>'&lt;/h1&gt;'</var>,
    $item[<var>'content_html'</var>],
  ]);

  <kbd>return</kbd> [
    <var>'@context'</var> =&gt; [
      <var>'https://www.w3.org/ns/activitystreams'</var>,
      [
        <var>'ostatus'</var> =&gt; <var>'http://ostatus.org#'</var>,
        <var>'atomUri'</var> =&gt; <var>'ostatus:atomUri'</var>,
        <var>'inReplyToAtomUri'</var> =&gt; <var>'ostatus:inReplyToAtomUri'</var>,
        <var>'conversation'</var> =&gt; <var>'ostatus:conversation'</var>,
        <var>'sensitive'</var> =&gt; <var>'as:sensitive'</var>,
        <var>'toot'</var> =&gt; <var>'http://joinmastodon.org/ns#'</var>,
        <var>'votersCount'</var> =&gt; <var>'toot:votersCount'</var>,
      ]
    ],
    <var>'id'</var> =&gt; <var>'https://imrannazar.com/ap/item?id='</var> . $item[<var>'id'</var>],
    <var>'url'</var> =&gt; <var>'https://imrannazar.com/ap/item?id='</var> . $item[<var>'id'</var>],
    <var>'atomUri'</var> =&gt; <var>'https://imrannazar.com/ap/item?id='</var> . $item[<var>'id'</var>],
    <var>'type'</var> =&gt; <var>'Note'</var>,
    <var>'attributedTo'</var> =&gt; <var>'https://imrannazar.com/ap/blog</var>',
    <var>'to'</var> =&gt; [<var>'https://www.w3.org/ns/activitystreams#Public'</var>],
    <var>'cc'</var> =&gt; [<var>'https://imrannazar.com/ap/followers'</var>],
    <var>'attachment'</var> =&gt; [],
    <var>'published'</var> =&gt; <kbd>date</kbd>(
      <var>'Y-m-d\TH:i:s\Z'</var>,
      <kbd>strtotime</kbd>($item[<var>'created'</var>])),
    <var>'content'</var> =&gt; $content,
    <var>'contentMap'</var> =&gt; [<var>'en'</var> =&gt; $content],
    <var>'summary'</var> =&gt; <kbd>null</kbd>,
    <var>'sensitive'</var> =&gt; <var>false</var>,
  ];
}</pre>
</samp>
<p>Then we can build out the publish action itself, which will need to send the note (wrapped in a <code>Create</code> object, as mentioned above) to each of the blog's followers:</p>
<samp>
 <h3>Controller: Publish action</h3>
 <pre><kbd>public function</kbd> publishAction($item) {
  $msg = [
    <var>'type'</var> =&gt; <var>'Create'</var>,
    <var>'to'</var> =&gt; [<var>'https://www.w3.org/ns/activitystreams#Public'</var>],
    <var>'cc'</var> =&gt; [<var>'https://imrannazar.com/ap/followers'</var>],
    <var>'object'</var> =&gt; $<kbd>this</kbd>-&gt;noteFormatter($item),
  ];

  $actors = <kbd>new</kbd> ActorModel();
  $followers = $actors-&gt;fetch_followers();
  <kbd>foreach</kbd> ($followers <kbd>as</kbd> $follower) {
    $<kbd>this</kbd>-&gt;send($follower[<var>'id'</var>], $msg);
  }
}</pre>
</samp>
<p>There is an inefficiency in this naive approach to publication, though. Let's say the blog has three followers, as follows:</p>
<ul>
 <li>Two9A@hachyderm.io</li>
 <li>alice@tech.lgbt</li>
 <li>charlie@hachyderm.io</li>
</ul>
<p>With the above code, we'll be connecting to Hachyderm twice to send the same event. Mastodon supports "shared inboxes" as discussed in the first part of this series<cite><sup>[1]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://imrannazar.com/articles/http-signatures-in-php">Imran Nazar, "Implementing HTTP Signatures with PHP and OpenSSL", May 2024</a></mark></cite>, to allow us to send the event once for each server that hosts any of our followers; to get the URLs for these shared inboxes, we'll need to interrogate the actor objects as stored in our database to extract the <code>sharedInbox</code> endpoints.</p>
<samp>
 <h3>Model: Shared inbox extraction</h3>
 <pre><kbd>public function</kbd> get_follower_shared_inboxes() {
  $st = $<kbd>this</kbd>->dbc->prepare(<var>'SELECT full_data FROM ap_actors WHERE follows_us=1 ORDER BY id'</var>);
  $st->execute();
  $inboxes = [];

  <kbd>foreach</kbd> ($st->fetchAll(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>) <kbd>as</kbd> $row) {
    $actor = <kbd>json_decode</kbd>($row[<var>'full_data'</var>], <var>true</var>);
    <kbd>if</kbd> (<kbd>isset</kbd>($actor[<var>'endpoints'</var>], $actor[<var>'endpoints'</var>][<var>'sharedInbox'</var>])) {
      $inboxes[$actor[<var>'endpoints'</var>][<var>'sharedInbox'</var>]] = <var>true</var>;
    } else {
      <s>// Some instances don't support shared inboxes</s>
      $inboxes[$actor[<var>'inbox'</var>]] = <var>true</var>;
    }
  }

  <s>// Use PHP's associative arrays as a deduping device</s>
  <kbd>return array_keys</kbd>($inboxes);
}</pre>
 <h3>Controller: Updated publish action</h3>
 <pre><kbd>public function</kbd> publishAction($item) {
  $msg = [
    <var>'type'</var> =&gt; <var>'Create'</var>,
    <var>'to'</var> =&gt; [<var>'https://www.w3.org/ns/activitystreams#Public'</var>],
    <var>'cc'</var> =&gt; [<var>'https://imrannazar.com/ap/followers'</var>],
    <var>'object'</var> =&gt; $<kbd>this</kbd>-&gt;noteFormatter($item),
  ];

  $actors = <kbd>new</kbd> ActorModel();
  $inboxes = $actors-&gt;get_follower_shared_inboxes();
  <kbd>foreach</kbd> ($inboxes <kbd>as</kbd> $inbox) {
    $<kbd>this</kbd>-&gt;send($inbox, $msg);
  }
}</pre>
</samp>
<p>Now, loading <code>/ap/publish</code> with the item you're looking to serve will send it out to the blog's followers. Pulling the item itself from the blog's database is left as an exercise for the reader, as the data structure of the blog will invariably vary.</p>
<h2>Storing comments</h2>
<p>When the newly published post appears on our followers' timelines, they may wish to reply to the post from within Mastodon. Doing this will, to no-one's surprise, cause an event analogous to our own publication of a <code>Note</code> to arrive at the blog, as the reply will be treated by ActivityPub as a <code>Note</code> in turn.</p>
<p>There are three circumstances in which a comment can arrive at our blog<cite><sup>[A]</sup><mark>(There are also second- or subsequent-level replies to one of the blog's posts, that don't mention the blog account directly. As these notes aren't directly in reply to our account, <em>and</em> don't mention the account, they will not be delivered to us as ActivityPub doesn't keep track of the root-level conversation ID.)</mark>:</p>
<ul>
 <li><strong>Comment on a post</strong>: These <code>Note</code> objects will have an <code>inReplyTo</code> value that matches the <code>id</code> of the blog article we published. Looking above, we see that our publish action sends out <code>Note</code> objects with an <code>id</code> starting: <code>https://imrannazar.com/ap/item?id=</code>, so any comments that arrive with this in their <code>inReplyTo</code> can be treated as top-level replies.</li>
 <li><strong>Reply to a comment that mentions the blog</strong>: Similarly to top-level comments, these objects will have a <code>inReplyTo</code>, but it will reference a previous comment's <code>id</code>. ActivityPub as implemented by Mastodon doesn't directly provide a "conversation ID", so we'll need to keep track of top-level replies and check the <code>inReplyTo</code> of an incoming comment to see if we've already stored it as a top-level comment's <code>id</code>.</li>
 <li><strong>Mention that isn't on a post</strong>: This will be delivered to us with no <code>inReplyTo</code>, so will need to be stored separately in some fashion.</li>
</ul>
<p>Any comments that arrive at our blog will have an <code>attributedTo</code> value which will allow us to retrieve data about the user who wrote the comment, so we can show the user's preferred name and avatar against the comment once we have it stored. Given that, we've already seen all the objects that will be involved: <code>Note</code> objects for the comments, and <code>Actor</code> objects for the user data, so let's look at the database table and model.</p>
<samp>
 <h3>Comments table in MySQL</h3>
 <pre>CREATE TABLE ap_comments(
  id VARCHAR(255) NOT NULL PRIMARY KEY,
  page_id INT NOT NULL,
  actor_id VARCHAR(255) NOT NULL,
  in_reply_to VARCHAR(255) NOT NULL,
  comment_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP(),
  content TEXT,
  full_data TEXT
);</pre>
 <h3>Comment data model</h3>
 <pre><kbd>class</kbd> CommentModel {
  <kbd>protected</kbd> $db; <s>// PDO MySQL connector</s>

  <s>// The inbox handler will parse out all the data we need here</s>
  <kbd>public function</kbd> insert($data) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'INSERT INTO ap_comments(
        id, page_id, actor_id, in_reply_to, content, full_data
      ) VALUES(
        :id, :page_id, :actor_id, :in_reply_to, :content, :full_data
      )'</var>
    );
    <kbd>foreach</kbd> ($data <kbd>as</kbd> $k =&gt; $v) {
      $st-&gt;bindValue(<var>":{$k}"</var>, $v);
    }
    $st-&gt;execute();
  }

  <kbd>public function</kbd> fetch($id) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'SELECT * FROM ap_comments WHERE id=:id'</var>
    );
    $st-&gt;bindValue(<var>':id'</var>, $id);
    $st-&gt;execute();

    <kbd>return</kbd> $st-&gt;fetch(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);
  }
}</pre>
</samp>
<p>The model here is a simple wrapper on the table, to support insertion of new comments. The controller's handler for receiving <code>Create</code> events is only slightly more complicated, as it needs to deal with the three cases mentioned above:</p>
<samp>
 <h3>Inbox handler for comment creation</h3>
 <pre><kbd>public function</kbd> createHandler($input) {
  <s>// For this implementation we're only handling creation of notes</s>
  <kbd>if</kbd> (!<kbd>isset</kbd>($input[<var>'object'</var>], $input[<var>'object'</var>][<var>'type'</var>])) {
    <kbd>throw new Exception</kbd>(<var>'Malformed create message'</var>);
  }
  <kbd>if</kbd> ($input[<var>'object'</var>][<var>'type'</var>] !== <var>'Note'</var>) {
    <kbd>throw new Exception</kbd>(<var>'Unsupported create message'</var>);
  }

  $cm = <kbd>new</kbd> CommentModel();
  $comment = $input[<var>'object'</var>];

  <s>// First, store the actor's data
  // As per the previous article, this will fetch from the remote server
  // if we don't already have the actor in our database</s>
  $actor = <kbd>new</kbd> ActorModel($comment[<var>'attributedTo'</var>]);

  $comment_data = [
    <var>'id'</var> =&gt; $comment[<var>'id'</var>],
    <var>'actor_id'</var> =&gt; $comment[<var>'attributedTo'</var>],
    <var>'content'</var> =&gt; $comment[<var>'content'</var>],
    <var>'full_data'</var> =&gt; <kbd>json_encode</kbd>($comment),
  ];

  $parent = <kbd>parse_url</kbd>($comment[<var>'inReplyTo'</var>]);

  <s>// If the parent is the blog post, we can infer the page ID
  // This also means the comment is top-level; in_reply_to is null</s>
  <kbd>if</kbd> ($parent[<var>'host'</var>] === <var>'imrannazar.com'</var>) {
    <kbd>parse_str</kbd>($parent[<var>'query'</var>], $parent_q);
    <kbd>if</kbd> (!<kbd>isset</kbd>($parent_q[<var>'id'</var>])) {
      <kbd>throw new Exception</kbd>(<var>'Mistargeted comment'</var>);
    }

    $comment_data += [
      <var>'page_id'</var> =&gt; $parent_q[<var>'id'</var>],
      <var>'in_reply_to'</var> =&gt; <var>null</var>,
    ];
  }

  <s>// Otherwise, we're receiving this because it's a
  // reply to an existing comment, or a mention</s>
  <kbd>else</kbd> {
    $parent_comment = $cm-&gt;get($comment[<var>'inReplyTo'</var>]);
    <kbd>if</kbd> (!$parent_comment) {
      <s>// Not associated with a particular page</s>
      $comment_data += [
        <var>'page_id'</var> =&gt; <var>0</var>,
        <var>'in_reply_to'</var> =&gt; <var>null</var>,
      ];
    } <kbd>else</kbd> {
      $comment_data += [
        <var>'page_id'</var> =&gt; $parent_comment[<var>'page_id'</var>],
        <var>'in_reply_to'</var> =&gt; $comment[<var>'inReplyTo'</var>],
      ];
    }
  }

  $cm-&gt;insert($comment_data);
}</pre>
</samp>
<p>Now we have a continual stream of comments and replies coming to our blog, we'll want a way to fetch and display them against a given post. Fortunately, storing both the page and parent comment IDs separately makes the data extraction relatively easy; displaying the comments is a matter of iterating over the top-level comments returned and recursing into the <code>children</code>, and won't be covered here as the handling is specific to a given blog's display implementation.</p>
<samp>
 <h3>Comment model: Fetch comments for a page</h3>
 <pre><kbd>public function</kbd> fetch_for_page($page_id) {
  $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
    <var>'SELECT
      c.id, c.in_reply_to, c.content, c.comment_date, c.actor_id,
      a.url, a.name, a.avatar_url
    FROM ap_comments c
    LEFT JOIN ap_actors a ON c.actor_id = a.id
    WHERE c.page_id = :page_id
    ORDER BY c.comment_date'</var>
  );
  $st-&gt;bindValue(<var>':page_id'</var>, $page_id);
  $st-&gt;execute();
  $data = $st-&gt;fetchAll(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);

  <s>// Build the tree by adding child comments as references</s>
  $comments_by_id = [];
  <kbd>foreach</kbd> ($data <kbd>as</kbd> $c) {
    $comments_by_id[$c[<var>'id'</var>]] = $c + [<var>'children'</var> =&gt; []];
    <kbd>if</kbd> ($c[<var>'in_reply_to'</var>]) {
      $comments_by_id[<var>'in_reply_to'</var>][<var>'children'</var>][] =
        &amp;$comments_by_id[$c[<var>'id'</var>]];
    }
  }

  <kbd>return</kbd> $comments_by_id;
}</pre>
</samp>
<p>It's also possible for a user to delete their comment once it's been left, and we'll want our blog's view to reflect that; the deletion of the comment will arrive at our blog as a <code>Delete</code> event. One thing to note here is that we're building a tree view of comments, but a comment can be deleted at any level of the tree and will still need to be made available as a place to hold its children; we can accomplish this by sanitising the comment content at the time of deletion, allowing <code>fetch_for_page</code> above to continue unchanged.</p>
<samp>
 <h3>Comment model: Sanitisation</h3>
 <pre><kbd>public function</kbd> sanitise($id) {
  $st->execute(
    <var>'UPDATE ap_comments
      SET content=NULL, actor_id=NULL, full_data=NULL
    WHERE id=:id'</var>
  );
  $st->bindValue(<var>':id'</var>, $id);
  $st->execute();
}</pre>
 <h3>Controller: Delete handler</h3>
 <pre><kbd>public function</kbd> deleteHandler($input) {
  $cm = <kbd>new</kbd> CommentModel();
  if ($cm->fetch($input[<var>'object'</var>][<var>'id'</var>])) {
    $cm->sanitise($input[<var>'object'</var>][<var>'id'</var>]);
  }
}</pre>
</samp>
<h2>Handling reactions</h2>
<p>Replying isn't the only thing that can happen to a post on Mastodon; it can also be favourited (or starred) and boosted by a user into their followers' timelines. Both of these are issued as ActivityPub events: favourites translate into ActivityPub <code>Like</code> events, and boosts into <code>Announce</code> events. As these both relate to pages on our blog, we can store them in a generic "interactions" table.</p>
<p>Unlike <code>Create</code> events which we've both seen and generated before, we haven't seen these new events, so let's have a look at an example of a <code>Like</code> event:</p>
<samp>
 <pre>{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://mastodon.social/users/0110100001101001#likes/183241819",
  "type": "Like",
  "actor": "https://mastodon.social/users/0110100001101001",
  "object": "https://imrannazar.com/ap/item?id=89"
 }</pre>
</samp>
<p>It turns out that <code>Like</code> and <code>Announce</code> events are fairly simple: the fields with which we need to be concerned are the actor and object, where the object is a canonical URL for one of the blog's pages. We can use similar URL parsing code to that which we used for comments, to pull out the page ID and store interactions against it in a new database table; we can then use that table to pull individual events and aggregate counts for a given page.</p>
<samp>
 <h3>Interactions table in MySQL</h3>
 <pre>CREATE TABLE ap_interactions(
  page_id INT NOT NULL,
  actor_id VARCHAR(255) NOT NULL,
  interaction ENUM('Like', 'Announce') NOT NULL,
  event_date TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP()
);</pre>
 <h3>Interaction model</h3>
 <pre><kbd>class</kbd> InteractionModel {
  <kbd>protected</kbd> $db; <s>// PDO MySQL connector</s>

  <kbd>public function</kbd> save($type, $page_id, $actor_id) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'INSERT INTO ap_interactions(interaction, page_id, actor_id)
      VALUES(:type, :page_id, :actor_id)'</var>
    );
    $st-&gt;bindValue(<var>':type'</var>, $type);
    $st-&gt;bindValue(<var>':page_id'</var>, $page_id);
    $st-&gt;bindValue(<var>':actor_id'</var>, $actor_id);
    $st-&gt;execute();
  }

  <kbd>public function</kbd> counts_for_page($page_id) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'SELECT interaction, COUNT(*) AS cnt
      FROM ap_interactions WHERE page_id=:page_id
      GROUP BY interaction'</vaR>
    );
    $st-&gt;bindValue(<var>':page_id'</var>, $page_id);
    $st-&gt;execute();

    <kbd>return</kbd> $st-&gt;fetchAll(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);
  }

  <kbd>public function</kbd> details_for_page($page_id) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'SELECT i.type, i.event_date,
        a.url, a.name, a.avatar_url
      FROM ap_interactions i
      LEFT JOIN ap_actors a ON i.actor_id = a.id
      WHERE i.page_id = :page_id'</var>
    );
    $st-&gt;bindValue(<var>':page_id'</var>, $page_id);
    $st-&gt;execute();

    <kbd>return</kbd> $st-&gt;fetchAll(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);
  }
}</pre>
 <h3>Controller: Interaction handlers</h3>
 <pre><kbd>protected function</kbd> interactionHandler($input) {
  $page = <kbd>parse_url</kbd>($input[<var>'object'</var>]);
  <kbd>if</kbd> ($page[<var>'host'</var>] !== <var>'imrannazar.com'</var>) {
    <kbd>throw new Exception</kbd>(<var>'Mistargeted interaction'</var>);
  }
  <kbd>parse_str</kbd>($page[<var>'query'</var>], $page_q);
  <kbd>if</kbd> (!<kbd>isset</kbd>($page_q[<var>'id'</var>])) {
    <kbd>throw new Exception</kbd>(<var>'Mistargeted interaction'</var>);
  }

  $im = <kbd>new</kbd> InteractionModel();
  $im-&gt;save($input[<var>'type'</var>], $page_q[<var>'id'</var>], $input[<var>'actor'</var>]);
}

<kbd>public function</kbd> likeHandler($input) {
  $<kbd>this</kbd>-&gt;interactionHandler($input);
}

<kbd>public function</kbd> announceHandler($input) {
  $<kbd>this</kbd>-&gt;interactionHandler($input);
}</pre>
</samp>
<p>Just as a user can decide to delete their comment on one of our posts, it's also possible to undo a favourite or boost in Mastodon; this will send an <code>Undo</code> event to us, where the <code>object</code> is a copy of the original interaction event. Unlike comments, however, there's no need for us to retain context of the interaction, so we can simply delete it from our database when the <code>Undo</code> comes in.</p>
<samp>
 <h3>Interaction model: Delete an interaction</h3>
 <pre><kbd>public function</kbd> delete($type, $page_id, $actor_id) {
    $st = $<kbd>this</kbd>-&gt;db-&gt;prepare(
      <var>'DELETE FROM ap_interactions WHERE
      type=:type AND page_id=:page_id AND actor_id=:actor_id'</var>
    );
    $st-&gt;bindValue(<var>':type'</var>, $type);
    $st-&gt;bindValue(<var>':page_id'</var>, $page_id);
    $st-&gt;bindValue(<var>':actor_id'</var>, $actor_id);
    $st-&gt;execute();
}</pre>
 <h3>Controller: Undo handler</h3>
 <pre><kbd>public function</kbd> undoHandler($input) {
  <kbd>if</kbd> (!<kbd>isset</kbd>($input[<var>'object'</var>], $input[<var>'object'</var>][<var>'type'</var>])) {
    <kbd>throw new Exception</kbd>(<var>'Malformed undo message'</var>);
  }

  <kbd>switch</kbd> ($input[<var>'object'</var>][<var>'type'</var>]) {
    <kbd>case</kbd> <var>'Like'</var>:
    <kbd>case</kbd> <var>'Announce'</var>:
      <s>// The original page being interacted with
      // is the Undo's object (the interaction)'s object</s>
      $page = <kbd>parse_url</kbd>($input[<var>'object'</var>][<var>'object'</var>]);
      <kbd>if</kbd> ($page[<var>'host'</var>] !== <var>'imrannazar.com'</var>) {
        <kbd>throw new Exception</kbd>(<var>'Mistargeted interaction'</var>);
      }
      <kbd>parse_str</kbd>($page[<var>'query'</var>], $page_q);
      <kbd>if</kbd> (!<kbd>isset</kbd>($page_q[<var>'id'</var>])) {
        <kbd>throw new Exception</kbd>(<var>'Mistargeted interaction'</var>);
      }

      $im = <kbd>new</kbd> InteractionModel();
      $im-&gt;delete(
        $input[<var>'object'</var>][<var>'type'</var>],
        $page_q[<var>'id'</var>],
        $input[<var>'actor'</var>]
      );
      <kbd>break</kbd>;

    <kbd>default</kbd>:
      <s>// Unhandled</s>
  }
}</pre>
</samp>
<p>And finally we come to the question I posed as the start: what happens when a user unfollows the blog? As it turns out, the <code>Follow</code> event is undone: an <code>Undo</code> event is sent to us. We just built out an <code>Undo</code> handler for interactions, so we can add events where the object is a <code>Follow</code>:</p>
<samp>
 <h3>Controller: Undo handler for follows</h3>
 <pre><kbd>public function</kbd> undoHandler($input) {
  ...
  <kbd>switch</kbd> ($input[<var>'object'</var>][<var>'type'</var>]) {
    ...
    <kbd>case</kbd> <var>'Follow'</var>:
      $actor = <kbd>new</kbd> ActorModel($input[<var>'actor'</var>]);
      $actor-&gt;set_follows_us(<var>false</var>);
      <kbd>break</kbd>;
  }
}</pre>
</samp>
<h2>All done: an ActivityPub-enabled blog</h2>
<p>As Eugen put it in his article on HTTP Signatures<cite><sup>[2]</sup><mark><a href="https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/">Eugen Rochko, "How to make friends and verify requests", Jul 2018</a></mark></cite> cited in the first part of this series:</p>
<blockquote>Primarily this means having a publicly accessible inbox and validating HTTP signatures. Once that works, everything else is just semantics.</blockquote>
<p>It took us two articles to get through the implementation of those semantics, but we're out the other side, and we should now have the framework of an ActivityPub-enabled blog: articles can be published on the Fediverse, and users can leave comments and interactions. Having those interactions display on the blog is, as mentioned earlier, an exercise for the reader and their particular blog framework.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">ActivityPub Follows in PHP</title>
 <link href="https://imrannazar.com/articles/activitypub-follow" rel="alternate" type="text/html" title="ActivityPub Follows in PHP" />
 <id>https://imrannazar.com/articles/activitypub-follow</id>
 <summary>Continuing a previous article on implementing ActivityPub support in PHP, this post looks at how to handle the most common types of message that might be expected to pass through a simple AP implementation.</summary>
 <category term="Series" />
 <published>Sun, 04 Aug 2024 07:12:40 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Previously<cite><sup>[1]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://imrannazar.com/articles/http-signatures-in-php">Imran Nazar, "Implementing HTTP Signatures with PHP and OpenSSL", May 2024</a></mark></cite> I looked at the main prerequisite for supporting ActivityPub on this blog, which is to handle the HTTP Signature specification as implemented by AP (and by Mastodon specifically). This time, let's look at the particular messages and operations that might arise in the course of running a blog that's connected to the Fediverse:</p>
<ul>
 <li><strong>Finding</strong> the blog and knowing the endpoints to communicate with it;</li>
 <li><strong>Following</strong> the blog to receive future posts in your timeline;</li>
 <li><strong>Publishing</strong> a post to the blog's followers;</li>
 <li><strong>Commenting</strong> on a post and having the comment appear on the blog;</li>
 <li><strong>Reacting</strong> to a post and having the reactions recorded on the blog;</li>
 <li><strong>Deleting</strong> a reply and having the blog remove it;</li>
 <li><strong>Undoing</strong> a follow or reaction and having the blog remove it.</li>
</ul>
<p>Aside from finding the blog, each of these has a direction in which it propagates, and only publishing a post is an outward event: a post is written on the blog, it's published and pushed out. The other events outlined above are inward events, which are received by the blog from the source server. We should deal with these in order though, as it won't make sense to publish to our followers without having received any follows, so we'll look at receiving events first.</p>
<h2>Finding the blog with WebFinger</h2>
<p>However, before any of the other events can happen, a user on Mastodon will need to find our blog, and the server on which they reside will need to know how to get messages to us. Mastodon uses WebFinger<cite><sup>[2]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://docs.joinmastodon.org/spec/webfinger/">Mastodon documentation, "WebFinger", Feb 2023</a></mark></cite> for this, and that means our blog will need to respond with <em>something</em> when the URL <code>/.well-known/webfinger</code> is loaded.</p>
<p>The documentation linked in note 2 states that the WebFinger endpoint will receive a request detailing which user is being "fingered", in order to determine how best to get information to that user. This is important for multi-user setups like Mastodon or Lemmy instances; fortunately, our blog is the kind of site that won't have multiple users. As such, we can ignore the body of the WebFinger request entirely, and serve a static response such as the following (which happens to be this blog's actual response).</p>
<samp>
 <h3>The blog's WebFinger response</h3>
 <pre>{
  <kbd>"subject"</kbd>: <var>"acct:blog@imrannazar.com"</var>,
  <kbd>"aliases"</kbd>: [
    <var>"https://imrannazar.com/@blog"</var>,
    <var>"https://imrannazar.com/ap/blog"</var>
  ],
  <kbd>"links"</kbd>: [
    {
      <kbd>"rel"</kbd>: <var>"http://webfinger.net/rel/profile-page"</var>,
      <kbd>"type"</kbd>: <var>"text/html"</var>,
      <kbd>"href"</kbd>: <var>"https://imrannazar.com/@blog"</var>
    },
    {
      <kbd>"rel"</kbd>: <var>"self"</var>,
      <kbd>"type"</kbd>: <var>"application/activity+json"</var>,
      <kbd>"href"</kbd>: <var>"https://imrannazar.com/ap/blog"</var>
    }
  ]
}</pre>
</samp>
<p>The above response indicates that, for the account <code>@blog@imrannazar.com</code> (which is the address I always hand out on Mastodon), its profile page (serving <code>text/html</code>) is <code>/@blog</code>, and its <code>self</code> (the canonical URL for ActivityPub's purposes) is <code>/ap/blog</code>; it's the latter of these which is important for our purposes, as it's the main repository of data regarding the blog and its available endpoints.</p>
<p>Let's have a quick look at this ActivityPub canonical URL: it serves a <code>Person</code> object with (almost) all the information a Mastodon instance might need to draw up a profile page for this account if it doesn't already have this information cached. We've already seen <code>Person</code> objects referenced in the previous instalment in relation to verifying an ActivityPub actor's public key, but let's have a look at the blog's actor data in more detail to see which endpoints we'll need to implement.</p>
<samp>
 <h3>The blog's actor object</h3>
 <pre>{
  "@context": [...],
  "publicKey": {...},

  "id": "https://imrannazar.com/ap/blog",
  "preferredUsername": "blog",
  "type": "Person",
  "name": "Imran Nazar's Blog",
  "url": "https://imrannazar.com/@blog",
  "summary": "&lt;p&gt;Imran Nazar: Things I've written over the years, a blog on software development topics with the occasional sci-fi short thrown in.&lt;/p&gt;",
  "published": "2006-09-22T00:00:00Z",

  "attachment": [
    {
      "name": "RSS feed",
      "type": "PropertyValue",
      "value": "&lt;a href=\"https://imrannazar.com/rss.xml\" rel=\"nofollow noreferrer noopener\" target=\"_blank\"&gt;https://imrannazar.com/rss.xml&lt;/a&gt;"
    }
  ],
  "icon": {
    "mediaType": "image/png",
    "type": "Image",
    "url": "https://imrannazar.com/assets/ap-icon.png"
  },
  "image": {
    "mediaType": "image/jpeg",
    "type": "Image",
    "url": "https://imrannazar.com/assets/ap-image.jpg"
  },

  "discoverable": true,
  "indexable": true,
  "manuallyApprovesFollowers": true,
  "memorial": false,

  "following": "https://imrannazar.com/ap/following",
  "followers": "https://imrannazar.com/ap/followers",
  "inbox": "https://imrannazar.com/ap/inbox",
  "outbox": "https://imrannazar.com/ap/outbox"
}</pre>
</samp>
<p>For our purposes, this can again be a static file served from the endpoint <code>/ap/blog</code>. There are a few groups of keys here:</p>
<ul>
 <li><strong>User information</strong>: Things like the ID (the canonical URL of this user), name, summary and date of publication (which for a <code>Person</code>-type object is the date the user was created);</li>
 <li><strong>Display data</strong>: This includes the avatar/icon, background/header image, and any additional URLs or links to be shown on the profile;</li>
 <li><strong>Behavioural flags</strong>: In this case, we want the account to be publicly visible ("discoverable") as well as come up in search results ("indexable"), but this is not a memorial account. The most important flag here is <code>manuallyApprovesFollowers</code>, as it determines what we do when a Follow request is received, but we'll come to that later;</li>
 <li><strong>Endpoints</strong>: These are the locations of interest to us. Following and Followers are read-only collections which inform any Mastodon instance reading them how many of each the blog has, and their canonical actor IDs; the Inbox is where a remote instance will send AP messages; and the Outbox is where an instance can expect messages from the blog to be coming from.</li>
</ul>
<p>So let's say a Mastodon user wants to follow this blog, and they have the address (<code>@blog@imrannazar.com</code>) but they're the first user on their instance to want to follow us. There are a few requests the remote instance will make in order to build up a complete profile:</p>
<ul>
 <li>First a WebFinger request is needed to find the actor ID; the URL for this is taken directly from the address given (<code>@blog@<strong>imrannazar.com</strong></code> leads us to https://imrannazar.com/.well-known/webfinger).</li>
 <li>The result contains a link of <code>rel: self</code> which in turn informs us where the actor resides, which when fetched contains the summary, icon, image and such.</li>
 <li>Once the remote instance has the actor data, it can then fetch the following and followers lists in order to show those counts.</li>
</ul>
<p>Having done all this, the remote instance is able to draw up a page that looks a little like this:</p>
<figure>
<img src="/content/img/ap-blog-profile.png" alt="Screenshot of this blog's profile page">
 <figcaption>Figure 2: Mastodon profile page for this blog</figcaption>
</figure>
<p>(We can see in this screenshot that the blog has six followers, but we haven't yet implemented <code>/ap/followers</code> to allow the remote instance to know that; we'll get to it though.)</p>
<h2>Receiving AP events</h2>
<p>Finally we have a profile page with an inviting Follow button, and the remote Mastodon instance knows where to send the request when that button is pressed: the actor's <code>inbox</code>. So what would one of those requests look like? Let's have a look at how that endpoint might translate to a controller in a PHP MVC framework like BirSaat<cite><sup>[3]</sup><mark><a href="https://github.com/Two9A/BirSaat">"BirSaat PHP MVC microframework", Imran Nazar, 2013</a></mark></cite>, so we can start logging the requests that come in:</p>
<samp>
 <pre><kbd>class</kbd> ApController <kbd>extends</kbd> bsControllerBase {
  <kbd>public function</kbd> inboxAction() {
    <kbd>if</kbd> ($<kbd>_SERVER</kbd>[<var>'REQUEST_METHOD'</var>] != <var>'POST'</var>) {
      <kbd>throw new</kbd> Exception(<var>'Inboxes are POSTed to'</var>);
    }

    $post = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
    <kbd>file_put_contents</kbd>(<var>'/tmp/ap.log'</var>, $post);
  }
}</pre>
</samp>
<p>It's rudimentary, but this code will allow us to see the last request that came in to <code>/ap/inbox</code>; the specification states that all messages will come in as POSTed JSON, so an additional check is made for the method of the request.  If I now press the Follow button on this blog, the following message comes in:</p>
<samp>
 <pre>{
  "@context": "https://www.w3.org/ns/activitystreams",
  "id": "https://hachyderm.io/af444650-1827-4bf7-94cd-0ec0b57bdb44",
  "type": "Follow",
  "actor": "https://hachyderm.io/users/Two9A",
  "object": "https://imrannazar.com/ap/blog"
}</pre>
</samp>
<p>Every ActivityPub message has an ID, which in our use case we don't need to track; the important things here are the <code>type</code> and the <code>actor</code> associated with the message. The <code>actor</code> who is following the blog <em>should</em> match up with the signature verification headers explained in the previous article, which will allow us to authenticate this as a valid message to be handled. So we can add a couple more clauses to our inbox handler before the message-specific handling begins:</p>
<samp>
 <pre><kbd>class</kbd> ApController <kbd>extends</kbd> bsControllerBase {
  <kbd>public function</kbd> inboxAction() {
    <kbd>if</kbd> ($<kbd>_SERVER</kbd>[<var>'REQUEST_METHOD'</var>] != <var>'POST'</var>) {
      <kbd>throw new</kbd> Exception(<var>'Inboxes are POSTed to'</var>);
    }

    $post = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
    <kbd>try</kbd> {
      <s>// Signature verification code from the previous article</s>
      $actor = $<kbd>this</kbd>-&gt;verifyHeaders();

      $input = <kbd>json_decode</kbd>($post, <var>true</var>);
      <kbd>if</kbd> (!$input) {
        <kbd>throw new</kbd> Exception(<var>'Malformed inbox message'</var>);
      }
      <kbd>if</kbd> ($actor[<var>'id'</var>] != $input[<var>'actor'</var>]) {
        <kbd>throw new</kbd> Exception(<var>'Inbox message misattributed'</var>);
      }

      $handler = <kbd>strtolower</kbd>($input[<var>'type'</var>]) . <var>'Handler'</var>;
      <kbd>if</kbd> (<kbd>is_callable</kbd>($<kbd>this</kbd>, $handler)) {
        $<kbd>this</kbd>-&gt;$handler($input);
      }
    } <kbd>catch</kbd> (<kbd>Exception</kbd> $e) {
      <s>// Any logging you may wish to perform</s>
      <kbd>throw</kbd> $e;
    }

    <s>// No response required except for a blank 200</s>
    <kbd>die</kbd>();
  }
}</pre>
</samp>
<h2>Handling Follows</h2>
<p>To follow the blog is to receive new posts when they're published, so we'll need to record the fact that this user is following us in order to send a publication event to their server when the time comes. We'll want a database table for this, and it so happens that this blog has its page structure data held in MySQL, so we'll make another table alongside the page list.</p>
<p>One thing to note is that signature verification for ActivityPub messages depends on us having the public key of the actor creating the message; if we don't already have the public key, we'll need to fetch it from the remote ActivityPub instance. In order to reduce the need to do this every time a message comes in, we can cache the actor object in the database once fetched, and use that for future verification requirements.</p>
<samp>
 <h3>Actors table in MySQL</h3>
 <pre>CREATE TABLE ap_actors(
  id VARCHAR(255) NOT NULL PRIMARY KEY,
  url VARCHAR(255) NOT NULL,
  name VARCHAR(255) NOT NULL,
  avatar_url TEXT,
  follows_us TINYINT(1) NOT NULL DEFAULT 0,
  full_data TEXT
);</pre>
 <h3>Actor data model: Cached fetch, preferring database first</h3>
 <pre><kbd>class</kbd> ActorModel {
  <kbd>protected</kbd> $db; <s>// PDO MySQL connector</s>

  <kbd>protected</kbd> $id;
  <kbd>public</kbd> $data;

  <kbd>public function __construct</kbd>($id = <kbd>null</kbd>) {
    <kbd>if</kbd> ($id) {
      $<kbd>this</kbd>-&gt;data = $<kbd>this</kbd>-&gt;cached_fetch($id);
      <kbd>return</kbd> $<kbd>this</kbd>-&gt;data;
    }
  }

  <kbd>public function</kbd> cached_fetch($id) {
    $<kbd>this</kbd>-&gt;id = $id;

    $st = $<kbd>this</kbd>-&gt;db-&gt;<kbd>prepare</kbd>(<var>'SELECT * FROM ap_actors WHERE id=:id'</var>);
    $st-&gt;<kbd>bindValue</kbd>(<var>':id'</var>, $id);
    $st-&gt;<kbd>execute</kbd>();

    $row = $st-&gt;<kbd>fetch</kbd>(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);
    <kbd>if</kbd> ($row) {
      <kbd>return json_decode</kbd>($row[<var>'full_data'</var>], <var>true</var>);
    }

    <s>// If we don't have the actor cached, fetch and save
    // See "Fetching the signing actor" from the previous article</s>
    $actor = $<kbd>this</kbd>-&gt;fetch_from_remote($id);
    <kbd>if</kbd> (!$actor) {
      <kbd>throw new Exception</kbd>(<var>'Actor not found'</var>);
    }

    $st = $<kbd>this</kbd>-&gt;db-&gt;<kbd>prepare</kbd>(<var>'
      INSERT INTO ap_actors(id, url, name, avatar_url, full_data)
      VALUES(:id, :url, :name, :avatar, :data)
    '</var>);
    $st-&gt;<kbd>bindValue</kbd>(<var>':id'</var>, $id);
    $st-&gt;<kbd>bindValue</kbd>(<var>':url'</var>, $actor[<var>'url'</var>]);
    $st-&gt;<kbd>bindValue</kbd>(<var>':name'</var>, $actor[<var>'name'</var>]);
    $st-&gt;<kbd>bindValue</kbd>(<var>':data'</var>, <kbd>json_encode</kbd>($actor));

    <s>// Some accounts don't have avatars</s>
    $st-&gt;<kbd>bindValue</kbd>(<var>':avatar'</var>, <kbd>isset</kbd>($actor[<var>'icon'</var>], $actor[<var>'icon'</var>][<var>'url'</var>])
      ? $actor[<var>'icon'</var>][<var>'url'</var>]
      : <var>null</var>
    );
    $st-&gt;<kbd>execute</kbd>();

    <kbd>return</kbd> $actor;
  }
}</pre>
</samp>
<p>Now we have the framework in place for handling messages, and an actor data model to store the fetched actors, all we need is to record the fact that the actor making this request wants to follow us:</p>
<samp>
 <h3>Controller: Follow handler</h3>
 <pre><kbd>private function</kbd> followHandler($input) {
  $actor = <kbd>new</kbd> ActorModel($input[<var>'actor'</var>]);
  $actor-&gt;set_follows_us(<var>true</var>);
}</pre>
 <h3>Model: Record the follow</h3>
 <pre><kbd>public function</kbd> set_follows_us($id, $follows) {
  $st = $<kbd>this</kbd>-&gt;db-&gt;<kbd>prepare</kbd>(
    <var>'UPDATE ap_actors SET follows_us = :f WHERE id = :id'</var>
  );
  $st-&gt;<kbd>bindValue</kbd>(<var>':id'</var>, $id);
  $st-&gt;<kbd>bindValue</kbd>(<var>':f'</var>, $follows);
  $st-&gt;<kbd>execute</kbd>();
}</pre>
</samp>
<h2>Accepting follows</h2>
<p>Except that doesn't quite work. If someone wants to follow this blog, and they hit Follow on the blog's profile page in their Mastodon instance, one would expect to see an "Unfollow" button the next time they view the blog, but instead we get "Cancel follow".</p>
<p>This happens because the remote instance is expecting a confirmation from us that the request to follow has been granted, as per this line from the blog's actor data:</p>
<samp>
 <h3><code>/ap/blog</code>: Blog actor data</h3>
 <pre>{
  "@context": [...],
  "publicKey": {...},
  ...
  "discoverable": true,
  "indexable": true,
  <kbd>"manuallyApprovesFollowers": true,</kbd>
  "memorial": false,
  ...
}</pre>
</samp>
<p>Just as the remote actor sent a message to our <code>inbox</code> to request the follow, we'll need to send an Accept-type message to their <code>inbox</code>. Luckily, we already have everything we need to do this: the actor's endpoints are part of their full data which we already have either cached or fetched, and the message being accepted is the follow we received.</p>
<samp>
 <pre><kbd>private function</kbd> followHandler($input) {
  $actor = <kbd>new</kbd> ActorModel($input[<var>'actor'</var>]);
  $actor-&gt;set_follows_us(<var>true</var>);

  <s>// See the previous article for detailed code on
  // signing and sending ActivityPub messages</s>
  $<kbd>this</kbd>-&gt;send($actor-&gt;data[<var>'inbox'</var>], [
    <var>'type'</var> =&gt; <var>'Accept'</var>,
    <var>'object'</var> =&gt; $input,
  ]);
}</pre>
</samp>
<p>And now we can circle back around to the blog's profile page, and specifically the "6 followers" that it shows. This data is fetched (if the instance doesn't already have a count of followers cached locally) from our actor's <code>followers</code> endpoint; this (and <code>following</code>) should return objects of type <code>Collection</code>. In theory, these collection endpoints should support pagination so any remote instance can fetch a full list of actor IDs, but for the purposes of this blog I don't foresee the list of followers growing to such an extent that serving a full list will cause undue load.</p>
<p>As with the <code>inbox</code> endpoint, these two collection endpoints will map to action methods in an MVC framework:</p>
<samp>
 <h3>Actor data model: Fetch actors who follow us</h3>
 <pre><kbd>public function</kbd> fetch_followers() {
  $st = $<kbd>this</kbd>-&gt;db-&gt;<kbd>prepare</kbd>(
    <var>'SELECT id, name, url, avatar_url FROM ap_actors WHERE follows_us = 1'</var>
  );
  $st-&gt;<kbd>execute</kbd>();
  <kbd>return</kbd> $st-&gt;<kbd>fetchAll</kbd>(<kbd>PDO</kbd>::<var>FETCH_ASSOC</var>);
}</pre>
 <h3><code>/ap/followers</code>: Endpoint to list followers</h3>
 <pre><kbd>public function</kbd> followersAction() {
  $actors = <kbd>new</kbd> ActorModel();
  $followers = $actors-&gt;fetch_followers();
  $<kbd>this</kbd>-&gt;view-&gt;set_format(<var>'json'</var>);
  <kbd>return</kbd> [
    <var>'@context'</var> =&gt; <var>'https://www.w3.org/ns/activitystreams'</var>,
    <var>'id'</var> =&gt; <var>'https://imrannazar.com/ap/followers'</var>,
    <var>'type'</var> =&gt; <var>'Collection'</var>,
    <var>'totalItems'</var> =&gt; <kbd>count</kbd>($followers),
    <var>'items'</var> =&gt; <kbd>array_map</kbd>(<kbd>function</kbd>($item) {
      <kbd>return</kbd> $item[<var>'id'</var>];
    }, $followers),
  ];
}</pre>
 <h3><code>/ap/following</code>: Users the blog is following</h3>
 <pre><kbd>public function</kbd> followingAction() {
  $<kbd>this</kbd>-&gt;view-&gt;set_format(<var>'json'</var>);
  <kbd>return</kbd> [
    <var>'@context'</var> =&gt; <var>'https://www.w3.org/ns/activitystreams'</var>,
    <var>'id'</var> =&gt; <var>'https://imrannazar.com/ap/followers'</var>,
    <var>'type'</var> =&gt; <var>'Collection'</var>,
    <var>'totalItems'</var> =&gt; <var>0</var>,
    <var>'items'</var> =&gt; [],
  ];
}</pre>
</samp>
<p>With the <code>followers</code> and <code>following</code> endpoints in place, and a way to listen to and respond to <code>Follow</code>-type messages, we now have a profile in the Fediverse (or at least on Mastodon) that can be followed. What happens when you press Unfollow on this profile?</p>
<p>As I've already gone on overly long for this post, we'll cover this and the other remaining operations in a third part; come back next time and we'll talk more about publishing, commenting and reactions.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">DeviantArt Community Guest Feature: When Art Meets Code</title>
 <link href="https://imrannazar.com/articles/art-and-code" rel="alternate" type="text/html" title="DeviantArt Community Guest Feature: When Art Meets Code" />
 <id>https://imrannazar.com/articles/art-and-code</id>
 <summary>First written for the DeviantArt Community group journal, Jun 2024. A short exploration of the connection between Piet Mondrian&#039;s abstract art and esoteric programming languages.</summary>
 <category term="Articles" />
 <published>Thu, 04 Jul 2024 18:33:36 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>This post was written for DeviantArt's Community group as a guest feature, in Jun 2024.</em></p>
<p>When people talk about the history of abstract art, the name of Piet Mondrian is sure to come up. It was Mondrian who, in 1922, was the first to throw out all pretence of realism in the search for deeper connection to the innate nature of things.</p>
<figure>
 <img src="/content/img/art-and-code-one.png" alt="A Mondrian piece with black lines on white canvas, some of the outer areas being coloured">
 <figcaption>Composition with Blue, Yellow, Red, Black and Grey (1922)<br>Piet Mondrian, Stedelijk Museum Amsterdam, via BBC<cite><sup>[1]</sup><mark><a href="https://www.bbc.com/culture/article/20220711-piet-mondrian-and-the-six-lines-that-made-a-masterpiece">"Piet Mondrian and the six lines that made a masterpiece"</a>, BBC Culture, 2022</mark></cite></figcaption>
</figure>
<p>Mondrian trained in traditional landscapes, and continued to paint still life flowers even while producing abstract art in the 1920's<cite><sup>[2]</sup><mark>David Shapiro, "Mondrian: Flowers", 1991; via <a href="https://en.wikipedia.org/wiki/Piet_Mondrian#cite_note-:1-31">Wikipedia</a></mark></cite> but as the curator of a Swiss collection of his works told the BBC:</p>
<blockquote>Minimalism is unthinkable without Mondrian; he was one of the first who really did this, this totally non-representational work? If you see modern as something which breaks with all traditions and defines everything new, then Mondrian's paintings of the 20s are very, very modern.</blockquote>
<p>The abstract works of Mondrian focus heavily on horizontal and vertical lines in black, and the filling of delineated areas with primary colours; as Mondrian would later explain in an essay from 1937, these lines "exist everywhere and dominate everything; their reciprocal action constitutes 'life'."</p>
<p>As it turns out, "everywhere" even includes fields of study that were barely known when Mondrian died in 1944, as his abstract style inspires the Piet programming language where images are programs, and different colours define various actions for the program to perform.</p>
<p>We don't usually think of images as computer programs. A computer program, though, can be represented in just about any way: if a given piece of code can be expressed in one "Turing-complete" form, it has been proven mathematically that any other "Turing-complete" form is equivalent.</p>
<p>To take a ridiculous example, a programming language exists based on travel between stations of the London Underground, and it's called Mornington Crescent<cite><sup>[3]</sup><mark><a href="https://esolangs.org/wiki/Mornington_Crescent">"Mornington Crescent"</a> on the Esolangs wiki, 2013</mark></cite>.</p>
<figure>
 <img src="/content/img/art-and-code-two.gif" alt="Interactive debugger session for Mornington Crescent Hello World">
 <figcaption>Interactive debugger for the Mornington Crescent programming language<br>Language specification by Timwi, debugger by Imran Nazar<cite><sup>[4]</sup><mark><a href="https://github.com/Two9A/mcresc">"mcresc: Mornington Crescent Interactive Debugger"</a>, Imran Nazar, 2016</mark></cite></figcaption>
</figure>
<p>So when David Morgan-Mar saw a painting by Piet Mondrian, and decided it would be good material for a programming language, it was no more ridiculous a concept than many others in the world of coding. Thus, the Piet language<cite><sup>[5]</sup><mark><a href="https://www.dangermouse.net/esoteric/piet.html">"Piet"</a>, David Morgan-Mar, last updated 2022</mark></cite> was born.</p>
<figure>
 <img src="/content/img/art-and-code-three.jpg" alt="Hello World in Piet, by Thomas Schoch">
 <figcaption>"Hello World" in the Piet programming language<br>Thomas Schoch, 2006<cite><sup>[6]</sup><mark><a href="https://retas.de/thomas/computer/programs/useless/piet/explain.html">"Hello, world! in Piet"</a>, Thomas Schoch, 2006</mark></cite></figcaption>
</figure>
<p>Programs in Piet are colourful. The Piet language uses more colours than Mondrian himself was wont to use, defining six colours in three shades, and giving meaning and context to each shade of colour as well as each direction of travel through the image; execution starts in the top left and moves through depending on the values of the pixels encountered.</p>
<p>There are many examples of programs that people have written in Piet<cite><sup>[7]</sup><mark><a href="https://www.dangermouse.net/esoteric/piet/samples.html">"Piet Program Gallery"</a>, David Morgan-Mar, last updated 2023</mark></cite>, including pieces intentionally designed to look more like abstract works than computer programs, but Piet probably claims the crown for the first programming language in which a piece of code has been written accidentally.</p>
<p>The work of Barbara Maahs<cite><sup>[8]</sup><mark><a href="https://barbaramaahs.de/malerei/">"Bilder, Barbara Maahs"</a>, Atelier Kunst 24</mark></cite>  is very much in the Mondrian tradition, with solid blocks of primary colour; she breaks away from the use of black dividing lines, often preferring direct contact between blocks. So it was that Piet Jarmatz saw a Maahs piece in a gallery, had a suspicion that it would run if plugged into a computer, and was able to convert it into a working Piet program<cite><sup>[9]</sup><mark><a href="https://gitlab.fabcity.hamburg/hofalab/piet-get-together">"Piet Get-Together"</a>, Piet Jarmatz, 2023</mark></cite> that takes typed-in letters and prints out their decimal ASCII values.</p>
<figure>
 <img src="/content/img/art-and-code-four.png" alt="Piet Get-Together">
 <figcaption>"Get-Together" by Barbara Maahs<br>Converted to Piet colour palette by Piet Jarmatz, 2023</figcaption>
</figure>
<p>And I think that's pretty neat.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">(Almost) Pure CSS Tooltips</title>
 <link href="https://imrannazar.com/articles/css-tooltips" rel="alternate" type="text/html" title="(Almost) Pure CSS Tooltips" />
 <id>https://imrannazar.com/articles/css-tooltips</id>
 <summary>Tooltips are the leading cause of hair loss for frontend developers: many hours have been lost fighting JavaScript frameworks to get their positioning just so. This article looks at how simple tooltips can be achieved with CSS, and the limits of the approach.</summary>
 <category term="Articles" />
 <published>Sun, 02 Jun 2024 08:26:04 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Recently I've found myself needing to insert endnotes and/or links to references when writing articles for this blog, if I want to cover some incidental detail of a topic under discussion without distracting from the main piece. I've used the word "endnote" here as the end of the post is a good place to put these asides, collated in one place out of the way; however, this can cause an issue for the diligent reader who'd like to look over an endnote at the time it's referenced. Having scrolled (or having been linked) to the bottom of the page, it can be problematic to come back up to where one was and continue with the main article.</p>
<p>To that end, I've instead started using inline tooltips for asides, which appear when the referential link is hovered over by the mouse (or tapped by the mobile user); this allows the aside to enrich the article without distracting from its flow.</p>
<figure>
 <img src="/content/img/css-tooltips-example.png" alt="Screenshot of an inline tooltip">
 <figcaption>Figure 1: An inline tooltip in the first part of my ActivityPub article series<cite><sup>[1]</sup><mark id="cite-1">Imran Nazar, <a href="https://imrannazar.com/articles/http-signatures-in-php">"HTTP Signatures in PHP and OpenSSL"</a>, May 2024</mark></cite></figcaption>
</figure>
<p>We can get almost all the way to a tooltip like this with CSS alone; let's have a look at how that works.</p>
<h2>CSS for tooltip positioning</h2>
<p>The most salient piece of CSS being used for these tooltips is the <code>position</code> rule: if an element on the page is positioned with the <code>absolute</code> value, it will anchor itself based on an offset from the nearest positioning context. That context can be the whole page, but more often it's a parent element that's been given the <code>relative</code> position value; the nearest relatively positioned parent to an absolutely positioned element will provide that context.</p>
<samp>
 <h3>HTML for a positioned tooltip</h3>
 <pre>&lt;p&gt;We discuss a topic, and then provide a reference &lt;cite&gt;
 &lt;sup&gt;[1]&lt;/sup&gt;
 &lt;mark&gt;&lt;em&gt;The Lord of the Rings&lt;/em&gt; (Harper/Collins), pg 293&lt;/mark&gt;
&lt;/cite&gt; which can make for further reading.&lt;/p&gt;</pre>
 <h3>CSS for the tooltip</h3>
 <pre><kbd>cite</kbd> {
  <kbd>position</kbd>: <var>relative</var>;
}
<kbd>cite sup</kbd> {
  <kbd>cursor</kbd>: <var>pointer</var>;
}
<kbd>cite mark</kbd> {
  <kbd>display</kbd>: <var>none</var>;
  <kbd>position</kbd>: <var>absolute</var>;
  <kbd>top</kbd>: <var>0.5em</var>;
  <kbd>left</kbd>: <var>0</var>;
}
<kbd>cite</kbd><var>:hover</var> <kbd>mark</kbd> {
  <kbd>display</kbd>: <var>block</var>;
}</pre>
</samp>
<h2>Display patches</h2>
<p>This gets us most of the way to a working tooltip already, but there are a few things we can do to help with the display:</p>
<ul>
 <li><strong>Background</strong>: As it stands, the tooltip <code>mark</code> is transparent, so the text of the tooltip renders over the top of the article and is hard to make out. This can be alleviated by giving the <code>mark</code> a <code>background</code> colour, and a <code>color</code> so the text can sit atop the background and be read well.</li>
 <li><strong>Width</strong>: Without a defined stipulation on width, the tooltip will only be as wide as the widest non-wrapping piece of content inside (generally, this would be the single longest word). We can make the tooltip more readable by giving it a minimum width based on the size of the viewport (the window being used to view the page); for example: <code>min-width: 30vw</code> to give the tooltip a width of at least 30% of the viewport, and more if the browser deems it necessary.</li>
 <li><strong>Z-index</strong>: Figure 1 shows our tooltip showing above text and images on the page. A detail of the implementation of images on this site is that some images (those with black text on a transparent background) are marked <em>invertable</em> so they're readable in dark mode; this adds a <code>filter: invert(1);</code> rule when dark mode is enabled at the body level. In turn, this puts the image in a new <em>stacking context</em><cite><sup>[2]</sup><mark>Mozilla Developer Network, <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_positioned_layout/Understanding_z-index/Stacking_context">Stacking context</a>, Feb 2024</mark></cite> which must be overridden by the tooltip with a <code>z-index</code> rule.</li>
 <li><strong>Accessibility</strong>: The tooltip content inside the <code>mark</code> is hidden by CSS unless one hovers on the <code>sup</code>; screen readers will generally disregard this content as invisible, meaning the additional context given by the aside won't be available in these browsers. This can be ameliorated by providing another CSS rule within a media query for non-screen users, as well as using <code>visibility</code> instead of <code>display</code> to control whether the tooltip appears.</li>
</ul>
<p>Putting these patches together gets us to the tooltips being used on this page, for which the CSS looks as follows:</p>
<samp>
 <pre><kbd>cite</kbd> {
  <kbd>position</kbd>: <var>relative</var>;
}
<kbd>cite sup</kbd> {
  <kbd>cursor</kbd>: <var>pointer</var>;
}
<kbd>cite mark</kbd> {
  <kbd>visibility</kbd>: <var>hidden</var>;
  <kbd>position</kbd>: <var>absolute</var>;
  <kbd>top</kbd>: <var>0.5em</var>;
  <kbd>left</kbd>: <var>0</var>;
  <kbd>z-index</kbd>: <var>2</var>;

  <s>/* Additional rules to add some nicety */</s>
  <kbd>color</kbd>: <kbd>var</kbd>(<var>--g-text</var>);
  <kbd>background</kbd>: <kbd>var</kbd>(<var>--g-bg</var>);
  <kbd>border</kbd>: <var>4px solid</var> <kbd>var</kbd>(<var>--g-border</var>);
  <kbd>border-radius</kbd>: <var>4px</var>;
  <kbd>padding</kbd>: <var>12px</var>;
  <kbd>min-width</kbd>: <var>30vw</var>;
}
<kbd>cite</kbd><var>:hover</var> <kbd>mark</kbd> {
  <kbd>visibility</kbd>: <var>visible</var>;
}

<kbd>@media not screen</kbd> {
  <kbd>cite mark</kbd> {
    <kbd>visibility</kbd>: <var>visible</var>;
  }
}</pre>
</samp>
<h2>Except that's not accessible</h2>
<p>For some screenreaders, this may be enough: the <code>visibility</code> rule puts the content of the tooltip into the page without having it initially visible. For Voiceover on macOS, however, the content needs to be <em>rendered</em> somewhere on the page so it can be read out.</p>
<p>Historically, the canonical way to have something render offscreen on a page without using <code>display</code> or <code>visibility</code> has been to position it off either the left or right edge of the screen. This still works, but positioning something off the right of the page is liable to push the scrollbar out, so we use negative <code>left</code> values to shunt the content off to the left; this places it in the DOM, visible to screenreaders, but not visible until we reset the <code>left</code> value.</p>
<samp>
 <pre><kbd>cite mark</kbd> {
  <kbd>position</kbd>: <var>absolute</var>;
  <kbd>top</kbd>: <var>0.5em</var>;
  <kbd>left</kbd>: <var>-9999px</var>;
}
<kbd>cite</kbd><var>:hover</var> <kbd>mark</kbd> {
  <kbd>left</kbd>: <var>0</var>;
}</pre>
</samp>
<p>With this positioning in place, Voiceover correctly picks up on the tooltip's presence in the page without having the tooltip render for sighted users, until the <code>sup</code> is hovered.</p>
<figure>
 <img alt="Screen capture of Chrome and Voiceover" src="/content/img/css-tooltips-voiceover.gif">
 <figcaption>Figure 2: Voiceover reading a section of my ActivityPub article</figcaption>
</figure>
<h2>Positioning on the right</h2>
<p>The only remaining issue with these tooltips is what happens when the <code>sup</code> trigger for the tooltip lies towards the right of the screen (anywhere past 70% across from the left of the viewport). In this case, bringing up the tooltip causes it to render with its <code>min-width</code> of 30% of the viewport, causing the right edge to be placed past the right edge of the content, and causing horizontal scroll.</p>
<p>Unfortunately, this is where we have to diverge from a pure-CSS solution, as the following doesn't exist in CSS as it stands:</p>
<samp>
 <h3>Hypothetical selector for elements towards the right of the screen</h3>
 <pre><kbd>cite</kbd>[<s>position-right &gt; 70vw</s>] <kbd>mark</kbd> {
  <kbd>left</kbd>: <var>auto</var>;
  <kbd>right</kbd>: <var>0</var>;
}</pre>
</samp>
<p>Instead, we must resort to JavaScript which can determine the rendered position of any tooltip triggers on the page, after the page has loaded. We can use the <code>querySelectorAll</code> method of the <code>document</code> to query for matching elements, and each matching element has a <code>getBoundingClientRect</code> method which will provide its position and size on the page.</p>
<p>Once we've determined whether the matching element is far enough to the right, we can add or remove a <code>class</code> to the element as appropriate. This can be done by using the corresponding methods of the element's <code>classList</code>.</p>
<samp>
 <h3>JavaScript: Tooltip positioner function</h3>
 <pre><kbd>window</kbd>.<kbd>onload</kbd> = <kbd>function</kbd>() {
  <kbd>const</kbd> tooltipPositioner = () =&gt; {
    <kbd>const</kbd> threshold = <kbd>window</kbd>.innerWidth * <var>0.7</var>;
    <kbd>document</kbd>.<kbd>querySelectorAll</kbd>(<var>'cite'</var>).<kbd>forEach</kbd>(el =&gt; {
      el.<kbd>classList</kbd>[
        el.<kbd>getBoundingClientRect</kbd>().x &gt; threshold
          ? <var>'add'</var>
          : <var>'remove'</var>
      ](<var>'right'</var>);
    });
  };

  tooltipPositioner();
};</pre>
 <h3>CSS: Rule for tooltips on the right</h3>
 <pre><kbd>cite</kbd>.<var>right</var> <kbd>mark</kbd> {
  <kbd>left</kbd>: <var>auto</var>;
  <kbd>right</kbd>: <var>0</var>;
}</pre>
</samp>
<h2>Repositioning after resize</h2>
<p>One consideration that needs to be made now that some tooltips can have a different behaviour for "is on the right of the screen" is what happens if the user resizes their browser window, and causes some tooltip triggers to move across the viewport as the content reflows. Fortunately, JavaScript offers the <code>ResizeObserver</code> which allows for a function to be run whenever an element resizes; as our positioning code is already in a function, setting up the observer against resizes on the document's <code>main</code> tag is fairly simple:</p>
<samp>
 <pre><kbd>const</kbd> tooltipPositioner = () =&gt; {
  ...
};
tooltipPositioner();
(<kbd>new ResizeObserver</kbd>(tooltipPositioner)).<kbd>observe</kbd>(
  <kbd>document</kbd>.<kbd>querySelector</kbd>(<var>'main'</var>)
);</pre>
</samp>
<p>It should be noted that the <code>ResizeObserver</code> runs every time the element changes size: if the user is resizing their browser window, this might fire a hundred times before the size of the window settles. For our purposes, as this is the only JavaScript running on the page, performance isn't a particular concern; if this tooltip code were to be used as part of a heavier framework, one may wish to use throttling mechanisms to ensure that the code is only run every so often while still remaining responsive to resize events.</p>
<p>But we almost got away without using any JS at all. With the new <code>popover</code> API rapidly rolling out to browsers as of the time of writing, it may soon be the case that even the CSS used here can be trimmed back.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Implementing HTTP Signatures with PHP and OpenSSL</title>
 <link href="https://imrannazar.com/articles/http-signatures-in-php" rel="alternate" type="text/html" title="Implementing HTTP Signatures with PHP and OpenSSL" />
 <id>https://imrannazar.com/articles/http-signatures-in-php</id>
 <summary>Part of a series on implementing ActivityPub support for this blog. A core tenet of ActivityPub is the generation and verification of signatures for messages, and this article looks at how that works in PHP.</summary>
 <category term="Series" />
 <published>Sat, 04 May 2024 12:20:39 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Over the last few months, I've slowly been adding ActivityPub support to this blog, focusing on Mastodon compatibility. Two central tenets apply to the operation of the AP protocol as it applies specifically to Mastodon:</p>
<ul>
 <li>An AP user (an "actor" in the protocol's terminology<cite><sup>[1]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://seb.jambor.dev/posts/understanding-activitypub/">Seb Jambor, "Understanding ActivityPub", May 2023</a></mark></cite>) can send an activity (for example, a Like on a post) and it will be broadcast to any servers hosting that user's followers;</li>
 <li>Receiving servers can verify that the activity was generated by the user in question.</li>
</ul>
<p>ActivityPub uses the HTTP Signature header for this second point, with public key encryption. It should be noted though, that there is a standard RFC for the Signature header<cite><sup>[2]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://datatracker.ietf.org/doc/rfc9421/">RFC 9421, "HTTP Message Signatures", Feb 2024</a></mark></cite> but AP was built before this RFC was released; instead, ActivityPub uses a draft version of the Signature specification<cite><sup>[3]</sup><mark><a target="_blank" rel="nofollower noreferrer" href="https://datatracker.ietf.org/doc/draft-cavage-http-signatures/12/">RFC 9421 draft 12, "Signing HTTP Messages", Oct 2019</a></mark></cite> which operates slightly differently.</p>
<figure class="invertable">
 <img src="/content/img/ap-sig-flow.png" alt="Flowchart of message signing and verification, for delivery of a Note to a follower">
 <figcaption>Figure 1: Signing and verification of an ActivityPub message</figcaption>
</figure>
<p>In Figure 1 above, we see the two halves of the process ActivityPub employs using the Signature header: the sender of an activity creates a message signed with their private key, and any receivers verify the message signature with the sender's public key. Let's first look at what goes into generation of the signature.</p>
<h2>Generating a signature</h2>
<p>The first thing we'll need is a Note, a message created by an actor; in this case, we'll use the creation of a toot by <code>alice@tech.lgbt</code><cite><sup>[A]</sup><mark>As it turns out, the example accounts being used for this article are both extant accounts, but <code>bob@mastodon.social</code> doesn't actually follow <code>alice@tech.lgbt</code> as of the time of writing.</mark></cite> which is represented by the following JSON object.</p>
<samp>
 <h3>Note written by the sender</h3>
 <pre>{
  "@context": {...},
  "id": "https://tech.lgbt/users/alice/statuses/12345678",
  "type": "Note",
  "url": "https://tech.lgbt/@alice/12345678",
  "attributedTo": "https://tech.lgbt/users/alice",
  "published": "2024-03-30T15:50:09Z",
  "to": ["https://www.w3.org/ns/activitystreams#Public"],
  "cc": ["https://tech.lgbt/users/alice/followers"],
  "content": "Hello followers!"
}</pre>
</samp>
<p>In order to broadcast this Note, ActivityPub requires that it be wrapped in a Create activity informing the recipients of the creation of an object:</p>
<samp>
 <h3>Message to be sent</h3>
 <pre>{
  "@context": {...},
  "id": "https://tech.lgbt/users/alice/statuses/12345678/activity",
  "type": "Create",
  "actor": "https://tech.lgbt/users/alice",
  "published": "2024-03-30T15:50:09Z",
  "to": ["https://www.w3.org/ns/activitystreams#Public"],
  "cc": ["https://tech.lgbt/users/alice/followers"],
  "object": {
    "id": "https://tech.lgbt/users/alice/statuses/12345678",
    "type": "Note",
    "url": "https://tech.lgbt/@alice/12345678",
    "attributedTo": "https://tech.lgbt/users/alice",
    "published": "2024-03-30T15:50:09Z",
    "to": ["https://www.w3.org/ns/activitystreams#Public"],
    "cc": ["https://tech.lgbt/users/alice/followers"],
    "content": "Hello followers!"
  }
}</pre>
</samp>
<p>Now we have the activity that will be broadcast to alice's followers, we can start the signature process; we'll need a fresh signature for each server that's receiving this message. For this example, alice has exactly one follower, on <code>mastodon.social</code>, so we'll need to send this message to the server's "shared inbox" at: <code>https://mastodon.social/inbox</code><cite><sup>[B]</sup><mark>Mastodon servers, by convention, have their shared inbox at <code>/inbox</code> but the canonical URL can be found in the actor's details, at the <code>endpoints.sharedInbox</code> key.</mark></cite> to be forwarded on to bob's personal inbox.</p>
<p>We first need a message digest, which by convention is an SHA-256 hash of the message content; in PHP, one might generate that as below.</p>
<samp>
 <h3>PHP code to generate the Digest header</h3>
 <pre>$message = <kbd>json_encode</kbd>([
  <var>'@context'</var> =&gt; [...],
  ...
]);

$digest = <var>'SHA-256='</var> . <kbd>hash</kbd>(<var>'sha256'</var>, $message);</pre>
</samp>
<p>The hash digest is one of the parts of the signature; other parts that we need to include are:</p>
<ul>
 <li><strong>Host</strong> of the remote server to which we're sending this message, in this case <code>mastodon.social</code>;</li>
 <li><strong>Request target</strong> is essentially the first line of the HTTP request we'll be making, in this case <code>post /inbox</code>;</li>
 <li><strong>Content type</strong> which isn't a requirement, but can be seen emitted by Mastodon hosts when communicating with each other. If this is part of the signature, it would be <code>application/activity+json</code>;</li>
 <li><strong>Date</strong> of the request, which can be verified by the other side to ensure this message isn't being replayed after the fact. The caveat here is that the date is in a particular format that's different to the date format in the activity JSON, for example: <code>Sat, 30 Mar 2024 15:50:09 GMT</code></li>
</ul>
<p>Pulling these together doesn't take too much doing in PHP:</p>
<samp>
 <h3>Collating signature parts</h3>
 <pre><s>// We'll be sending the date separately, so take one fixed point</s>
$dt = <kbd>date</kbd>(<var>"D, d M Y H:i:s \G\M\T"</var>);
$url = <var>'https://mastodon.social/inbox'</var>;

$urlparts = <kbd>parse_url</kbd>($url);
$sigparts = [
  <var>'(request-target)'</var> =&gt; <var>'post '</var> . $urlparts[<var>'path'</var>],
  <var>'host'</var> =&gt; $urlparts[<var>'host'</var>],
  <var>'date'</var> =&gt; $dt,
  <var>'digest'</var> =&gt; $digest,
  <var>'content-type'</var> =&gt; <var>'application/activity+json'</var>,
];
$sigsrc = <kbd>join</kbd>(<var>"\n"</var>, <kbd>array_map</kbd>(
  <kbd>fn</kbd>($k, $v) =&gt; <var>"{$k}: {$v}"</var>,
  <kbd>array_keys</kbd>($sigparts),
  <kbd>array_values</kbd>($sigparts)
));</pre>
 <h3>Our collated signature source</h3>
 <pre>(request-target): post /inbox
host: mastodon.social
date: Sat, 30 Mar 2024 15:50:09 GMT
digest: SHA-256=ce9a290f805f....1bbcf5104ad7550191201
content-type: application/activity+json</pre>
</samp>
<p>Once we have the collated signature source, we can invoke OpenSSL to sign the string with the private part of alice's key pair. PHP's OpenSSL bindings expect a PEM-formatted file for this, which for this example we're storing in <code>/etc/pki</code> somewhere:</p>
<samp>
 <h3>Signing the collated signature source</h3>
 <pre><kbd>openssl_sign</kbd>($sigsrc, $signature, <kbd>openssl_get_privatekey</kbd>(
  <kbd>file_get_contents</kbd>(<var>'/etc/pki/activitypub/alice/private.pem'</var>),
  <var>'key_passphrase'</var>
), <var>OPENSSL_ALGO_SHA256</var>);</pre>
</samp>
<p>This leaves the signature in <code>$signature</code>, in binary. Our last step in signing the request is to format the signature according to the signing spec, detailing what we've used to generate this signature, and which key was involved.</p>
<p>For the remote end to be able to verify the signature, we'll need to provide a URL at which alice's public key can be fetched; in the ActivityPub protocol, this is included as part of the details of an actor, as we'll see when we go through verification at the other end.</p>
<samp>
 <h3>Final header generation</h3>
 <pre>$sig_header_parts = [
  <var>'keyId'</var> =&gt; <var>'https://tech.lgbt/users/alice#main-key'</var>,
  <var>'algorithm'</var> =&gt; <var>'rsa-sha256'</var>,
  <var>'headers'</var> =&gt; <kbd>join</kbd>(<var>' '</var>, <kbd>array_keys</kbd>($sigparts)),
  <var>'signature'</var> =&gt; <kbd>base64_encode</kbd>($signature),
];
$headers = [
  <var>'Accept: application/activity+json'</var>,
  <var>'Content-Type: application/activity+json'</var>,
  <var>'Host: '</var> . $urlparts[<var>'host'</var>],
  <var>'Date: '</var> . $dt,
  <var>'Digest: '</var> . $digest,
  <var>'Signature: '</var> . <kbd>join</kbd>(<var>','</var>, <kbd>array_map</kbd>(
    <kbd>fn</kbd>($k, $v) =&gt; <var>"{$k}=\"{$v}\""</var>,
    <kbd>array_keys</kbd>($sig_header_parts),
    <kbd>array_values</kbd>($sig_header_parts)
  )),
];</pre>
 <h3>Final list of headers</h3>
 <pre>Accept: application/activity+json
Content-Type: application/activity+json
Host: mastodon.social
Date: Sat, 30 Mar 2024 15:50:09 GMT
Digest: SHA-256=ce9a290f805f....1bbcf5104ad7550191201
Signature: keyId="https://tech.lgbt/users/alice#main-key",algorithm="rsa-sha256",headers="(request-target) host date digest content-type",signature="xmpTJEEjodgUP5H....BrN3DwZGy7DoTfRQ=="</pre>
</samp>
<p>And we're ready to send alice's message over to bob's Mastodon instance, with the headers indicating that it's been signed by alice and a digest hash to allow the message content to also be verified.</p>
<h2>Verifying a signature</h2>
<p>As per Figure 1, when <code>mastodon.social</code> receives alice's activity it will first verify that this is a both a valid activity and that it's appropriately signed, and then the server will drop the message into any of alice's followers that are recorded as active on the instance.</p>
<p>The first step is to extract the signature and its components. We've seen from the generation code that this is passed through as a HTTP header, so if we place a dumping script at <code>/inbox</code> it might see something like this:</p>
<samp>
 <h3>Dumping script to see what lands at /inbox</h3>
 <pre>&lt;?php
$input = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
<kbd>var_dump</kbd>([$<kbd>_SERVER</kbd>, $message]);</pre>
 <h3>Output of the dumping script</h3>
 <pre>array(2) {
  [0]=&gt;
  array(29) {
    ["USER"]=&gt;
    string(8) "www-data"
    ...
    ["HTTP_CONTENT_TYPE"]=&gt;
    string(25) "application/activity+json"
    ["HTTP_DATE"]=&gt;
    string(29) "Sat, 30 Mar 2024 15:50:09 GMT"
    ["HTTP_DIGEST"]=&gt;
    string(52) "SHA-256=ce9a290f805f..."
    ["HTTP_SIGNATURE"]=&gt;
    string(502) "keyId="https://tech.lgbt/users/alice#main-key",algori..."
    ...
    ["REQUEST_METHOD"]=&gt;
    string(4) "POST"
    ["REQUEST_URI"]=&gt;
    string(6) "/inbox"
  }
  [1]=&gt;
  string(1347) "{"@context":{..."
}</pre>
</samp>
<p>As we'd expect for PHP, the HTTP headers come to the script in the <code>$_SERVER</code> superglobal, with the <code>HTTP_</code> prefix, so we can extract the parts of the signature that we need from <code>$_SERVER['HTTP_SIGNATURE']</code>.</p>
<p>It should be noted that commas only appear in the signature to delineate the parts; each of the parts themselves is either a URL or a piece of text that won't contain a comma. This means we can treat the signature string as an INI file and parse it fairly simply, with some deft string replacement:</p>
<samp>
 <pre><kbd>if</kbd> (!<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'HTTP_SIGNATURE'</var>])) {
  <kbd>throw new Exception</kbd>(<var>'No signature'</var>);
}
$sigconf = <kbd>parse_ini_string</kbd>(
  <kbd>strtr</kbd>($<kbd>_SERVER</kbd>[<var>'HTTP_SIGNATURE'</var>], [<var>","</var> =&gt; <var>"\n"</var>])
);
if (!<kbd>isset</kbd>(
  $sigconf[<var>'keyId'</var>],
  $sigconf[<var>'algorithm'</var>],
  $sigconf[<var>'headers'</var>],
  $sigconf[<var>'signature'</var>]
)) {
  <kbd>throw new Exception</kbd>(<var>'Malformed signature'</var>);
}</pre>
</samp>
<p>The first item in <code>$sigconf</code> is the URL of the public half of the key pair used to generate this signature. In real-life usage we might expect to have this already cached or stored locally, but if we don't it will need to be fetched, which is something we can make happen through the <code>curl</code> extension.</p>
<p>We've already seen that ActivityPub objects are passed back and forth with a MIME content type of <code>application/activity+json</code>, so we'll need to set that as the MIME type we'll be expecting to <code>Accept</code>. What we get back is an ActivityPub actor object:</p>
<samp>
 <h3>Fetching the signing actor</h3>
 <pre>$c = <kbd>curl_init</kbd>();
<kbd>curl_setopt_array</kbd>($c, [
  CURLOPT_URL =&gt; $sigconf[<var>'keyId'</var>],
  CURLOPT_TIMEOUT =&gt; <var>5</var>,
  CURLOPT_SSL_VERIFYPEER =&gt; <var>true</var>,
  CURLOPT_FOLLOWLOCATION =&gt; <var>true</var>,
  CURLOPT_RETURNTRANSFER =&gt; <var>true</var>,
  CURLOPT_HTTPHEADER =&gt; [
    <var>'Accept: application/activity+json'</var>,
  ],
]);
$r = <kbd>curl_exec</kbd>($c);
<kbd>curl_close</kbd>($c);

<kbd>if</kbd> (!$r) {
  <kbd>throw new Exception</kbd>(<var>'User information not available'</var>);
}
$actor = <kbd>json_decode</kbd>($r, <var>true</var>);
<kbd>if</kbd> (!$actor) {
  <kbd>throw new Exception</kbd>(<var>'User information not decodable'</var>);
}</pre>
 <h3>The actor object (formatted)</h3>
 <pre>{
  "@context": {...},
  "id": "https://tech.lgbt/users/alice",
  "type": "Person",
  "following": "https://tech.lgbt/users/alice/following",
  "followers": "https://tech.lgbt/users/alice/followers",
  ...
  "url": "https://tech.lgbt/@alice",
  "publicKey": {
    "id": "https://tech.lgbt/users/alice#main-key",
    "owner": "https://tech.lgbt/users/alice",
    "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhk..."
  },
  "endpoints": {
    "sharedInbox": "https://tech.lgbt/inbox"<cite><sup>[C]</sup><mark>This is the key mentioned in note B.</mark></cite>
  }
}</pre>
</samp>
<p>The signing actor's public key comes through in the <code>publicKey</code> block, so we'll hold onto that for the verification later. It's worth double-checking that the key we've been served as part of the actor is the same key that was used to sign the message, which we can do by comparing the key's <code>id</code> with the <code>keyId</code> that came through from the signature.</p>
<p>We'll be using the <code>openssl</code> extension to perform verification, and we need to translate the PEM-formatted public key to a binary format for internal use by first calling <code>openssl_get_publickey</code>:</p>
<samp>
 <pre><kbd>if</kbd> (!<kbd>isset</kbd>(
  $actor[<var>'publicKey'</var>],
  $actor[<var>'publicKey'</var>][<var>'id'</var>],
  $actor[<var>'publicKey'</var>][<var>'publicKeyPem'</var>]
)) {
  <kbd>throw new Exception</kbd>(<var>'Missing public key'</var>);
}

<kbd>if</kbd> ($actor[<var>'publicKey'</var>][<var>'id'</var>] !== $sigconf[<var>'keyId'</var>]) {
  <kbd>throw new Exception</kbd>(<var>'Misattributed public key'</var>);
}

$pubkey = <kbd>openssl_get_publickey</kbd>($actor[<var>'publicKey'</var>][<var>'publicKeyPem'</var>]);
<kbd>if</kbd> (!$pubkey) {
  <kbd>throw new Exception</kbd>(<var>'Malformed public key'</var>);
}</pre>
</samp>
<p>We're almost done with the first block of verification from Figure 1; the final stage before verifying the signature against alice's public key is to build the signature string based on the <code>headers</code> key. We'll want to tack together the headers given to us, as specified in the order therein.</p>
<p>There are two things to watch out for here:</p>
<ul>
 <li>HTTP headers are passed through <code>$_SERVER</code> as previously mentioned, but they're transformed into uppercase and hyphens are switched out for underscores;</li>
 <li>The <code>(request-target)</code> signature part is a special case, as it consists of the request <em>method</em> (in lowercase) and the request <em>URI</em>, both of which come through in <code>$_SERVER</code> separately.</li>
</ul>
<samp>
 <pre>$sigparts = [];
<kbd>foreach</kbd> (<kbd>explode</kbd>(<var>' '</var>, $sigconf['headers']) <kbd>as</kbd> $hdr) {
  <kbd>if</kbd> ($hdr === <var>'(request-target)'</var>) {
    $sigparts[] = <kbd>sprintf</kbd>(
      <var>'%s: %s %s'</var>,
      $hdr,
      <kbd>strtolower</kbd>($<kbd>_SERVER</kbd>[<var>'REQUEST_METHOD'</var>]),
      $<kbd>_SERVER</kbd>[<var>'REQUEST_URI'</var>]
    );
  } <kbd>else</kbd> {
    $received_hdr = <var>'HTTP_'</var> . <kbd>strtoupper</kbd>(<kbd>strtr</kbd>($hdr, [<var>'-'</var> =&gt; <var>'_'</var>));
    <kbd>if</kbd> (!<kbd>isset</kbd>($<kbd>_SERVER</kbd>[$received_hdr)) {
      <kbd>throw new Exception</kbd>(<var>'Missing signature part: '</var> . $hdr);
    }

    $sigparts[] = <kbd>sprintf</kbd>(<var>'%s: %s'</var>, $hdr, $<kbd>_SERVER</kbd>[$received_hdr]);
  }
}</pre>
</samp>
<p>With the signature constructed, we can finally call out to OpenSSL to perform the verification against alice's public key, which we loaded into binary format earlier. Here, we're assuming that the <code>algorithm</code> specified is a well-known value to OpenSSL like <code>rsa-sha256</code> (the key algorithm used by Mastodon instances at time of writing), but it can be useful to verify this against a list of allowed values before proceeding if you're feeling particularly paranoid.</p>
<samp>
 <pre><kbd>if</kbd> (!<kbd>openssl_verify</kbd>(
  <kbd>join</kbd>(<var>"\n"</var>, $sigparts),
  <kbd>base64_decode</kbd>($sigconf[<var>'signature'</var>]),
  $pubkey,
  <kbd>strtoupper</kbd>($sigconf[<var>'algorithm'</var>])
)) {
  <kbd>throw new Exception</kbd>(<var>'Signature verification failed'</var>);
}</pre>
</samp>
<p>Finally, with the message's origin verified, we can proceed to verify the message content against the digest provided. Again in this case, we're supporting a limited subset of the possible hash algorithms that could be used for the digest, as Mastodon invariably sends messages with a SHA256 digest:</p>
<samp>
 <pre><kbd>list</kbd>($digest_algo, $digest_hash) = <kbd>explode</kbd>(<var>'='</var>, $<kbd>_SERVER</kbd>[<var>'HTTP_DIGEST'</var>]);
<kbd>switch</kbd> ($digest_algo) {
  <kbd>case</kbd> <var>'SHA256'</var>:
    $input_digest = <kbd>hash</kbd>(<var>'sha256'</var>, $input);
    <kbd>break</kbd>;

  <kbd>default</kbd>:
    <kbd>throw new Exception</kbd>(<var>'Unsupported digest algorithm'</var>);
}
<kbd>if</kbd> ($input_digest !== $digest_hash) {
  <kbd>throw new Exception</kbd>(<var>'Digest verification failed'</var>);
}</pre>
</samp>
<p>And if we made it this far, past all the exception points, we have a valid ActivityPub message that's verified to have been signed by the owner of the originating key.</p>
<h2>Further reading</h2>
<p>It's always dangerous on this blog to promise a "next time", but: next time we'll look at the particular ActivityPub messages that we'd want to support when adding AP support to a blog, and the surrounding architecture of user and inbox handling.</p>
<p>More information about ActivityPub and the specifics of the Mastodon implementation can be found in the third part of Seb Jambor's series on Understanding ActivityPub<cite><sup>[4]</sup><mark><a href="https://seb.jambor.dev/posts/understanding-activitypub-part-3-the-state-of-mastodon/">Seb Jambor, "The State of Mastodon", August 2023</a></mark></cite>; the PHP implementation we've covered here is an expansion and explanation based on Terence Eden's single-file PHP integration of ActivityPub<cite><sup>[5]</sup><mark><a href="https://shkspr.mobi/blog/2024/02/activitypub-server-in-a-single-file/">Terence Eden, "AcitvityPub Server in a Single File", Feb 2024</a></mark></cite> which moves over the signature stage relatively quickly, and incorporates Eugen Rochko's insights on signature verification<cite><sup>[6]</sup><mark><a href="https://blog.joinmastodon.org/2018/07/how-to-make-friends-and-verify-requests/">Eugen Rochko, "How to make friends and verify requests", Jul 2018</a></mark></cite>.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Slow-Roll Livecoding: Proxying a REST API with PHP</title>
 <link href="https://imrannazar.com/articles/proxying-rest-in-php" rel="alternate" type="text/html" title="Slow-Roll Livecoding: Proxying a REST API with PHP" />
 <id>https://imrannazar.com/articles/proxying-rest-in-php</id>
 <summary>Sometimes you need to proxy an API, and you may not necessarily have the resources or wherewithal to install dedicated proxying infrastructure. Let&#039;s try to write a proxy in PHP, and see what troubles we run into.</summary>
 <category term="Articles" />
 <published>Thu, 04 Apr 2024 09:37:38 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Now and then I run into a situation where I'd like to access a REST API from Postman (or one of its less account-encumbered alternatives for API testing) running locally, but the remote is firewalled and the API provider has only added production and staging IPs to the allowlist. This might be a familiar situation to integration developers, and it leaves you with only a few options:
 <dl>
  <dt>Testing from the server</dt>
  <dd>As production and staging are in the allowlist, you can <em>simply</em> connect to those IPs and perform tests from there. This does, however, presume a couple of things:
   <ul>
    <li><strong>You have access to those servers</strong>: A fly-by-night webshop may hand out root access to the server machines and allow their integration developers to hack directly thereupon, but a more organised place may have access restrictions and only allow their infrastructure team direct access.</li>
    <li><strong>Those servers exist</strong>: An increasingly common setup is for APIs and integrations to run on ephemeral servers (often referred to as "serverless" architecture) with Networking Magic to allow them to present as a fixed IP; in this case there's no machine to connect to in order to perform tests.</li>
   </ul>
  </dd>
  <dt>Forwarding the remote</dt>
  <dd>Another option is to use NAT-based forwarding to expose the remote API: for example, if the third-party REST API is served from <code>https://their-end.io/api</code> you can use NAT to expose this as <code>https://your-end.com:8443/api</code> by forwarding connections on port 8443 to <code>their-end.io</code> port 443.</dd>
  <dd>This does, however, involve roping in the infrastructure people to either perform <code>iptables</code>-based incantations to set up the NAT, or even more arcane spells to set up containerised NAT. Direct forwarding of the connection also means you lose the opportunity to log usage of the remote API, if you were seeking to keep track of who's connecting.</dd>
  <dt>Proxying the remote</dt>
  <dd>Perhaps the most flexible option is to proxy the remote API: to present an interface to the interface. This allows us to access the API from locations outside the allowlist, while giving us the chance to log access if so required, and has the advantage of being possible to set up in two ways: either through a dedicated proxying package like <code>nginx-proxy</code>, or through code-level changes only.</dd>
 </dl>
</p>
<p>Having explored the options, here we'll be looking at a code-level proxy written in PHP.</p>
<h2>What we're looking to proxy</h2>
<p>Our example remote API to which we'd like access is fairly standard as REST goes, offering the following operations:
 <ul>
  <li><code>GET /accounts</code>: Fetch a list of registered accounts, with each account having a canonical URL of <code>/accounts/&lt;uuid&gt;</code> as part of the returned JSON;</li>
  <li><code>POST /accounts</code>: Create a new account given the required details in JSON, returning a canonical URL;</li>
  <li><code>PUT /accounts/&lt;uuid&gt;</code>: Update an account by UUID;</li>
  <li><code>DELETE /accounts/&lt;uuid&gt;</code>: Delete an account by UUID.</li>
 </ul>
</p>
<p>We'll be using the <code>curl</code> extension to PHP, which is bundled by default, to send the request on behalf of what was received by our proxy, and to print out what was returned. Let's look at how that might work, as a first cut:</p>
<samp>
 <h3>First cut at a proxy script</h3>
 <pre><kbd>define</kbd>(<var>'REMOTE_URL'</var>, <var>'https://their-end.io/api/'</var>);
<kbd>define</kbd>(<var>'OUR_URL'</var>, <var>'https://your-end.com/apiproxy.php'</var>);

$params = $<kbd>_GET</kbd>;
$curl_params = [
  <var>CURLOPT_URL</var>            =&gt; <var>REMOTE_URL</var> . <var>'?'</var> . <kbd>http_build_query</kbd>($params),
  <var>CURLOPT_TIMEOUT</var>        =&gt; <var>30</var>,
  <var>CURLOPT_RETURNTRANSFER</var> =&gt; <var>true</var>,
  <var>CURLOPT_FOLLOWLOCATION</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYHOST</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYPEER</var> =&gt; <var>true</var>,
  <var>CURLOPT_CUSTOMREQUEST</var>  =&gt; $_SERVER[<var>'REQUEST_METHOD'</var>],
];

<s>// Anything with a POSTed body needs the body transferring</s>
<kbd>if</kbd> ($_SERVER[<var>'REQUEST_METHOD'</var>] !== <var>'GET'</var>) {
  $curl_params[<var>CURLOPT_POSTFIELDS</var>] = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
}

$c = <kbd>curl_init</kbd>();
<kbd>curl_setopt_array</kbd>($c, $curl_params);
$r = <kbd>curl_exec</kbd>($c);
<kbd>curl_close</kbd>($c);
<kbd>echo</kbd> $r;</pre>
</samp>
<p>If we send a request to our <code>apiproxy.php</code>, we might get back something like this:</p>
<samp>
 <h3>Output of our first-cut</h3>
 <pre>$ curl https://your-end.com/apiproxy.php
&lt;html&gt;&lt;body&gt;
&lt;h1&gt;Error 404 Not Found&lt;/h1&gt;
&lt;/body&gt;&lt;/html&gt;</pre>
</samp>
<p>So that didn't work so well; we've got two problems here. Our request went to <code>/api</code> at the remote end, but we need some additional qualifier to get the request to <code>/api/accounts</code>, ideally as part of the URL itself. Additionally, our request to the remote came back with a 404 error, but we just printed the output: that means our proxy script returned a 200, and discarded any other headers that may have come back.</p>
<h2>Passing the URL with Rewrite</h2>
<p>This is where we cheat a little: our proxy ends up needing a small amount of webserver configuration as well as the PHP script. In our case, we're running on a LAMP stack so Apache is our webserver; that means we can slot a <code>.htaccess</code> file in place which translates the URL into something the script can use:</p>
<samp>
 <h3>.htaccess Rewrite rule to translate the URL</h3>
 <pre><kbd>RewriteEngine</kbd> <var>On</var>
<kbd>RewriteRule</kbd> ^/api-proxy/(.*)$ <var>/apiproxy.php?__url=$1</var> [<kbd>QSA</kbd>]</pre>
</samp>
<p>This instructs Apache to listen out for URLs starting <code>/api-proxy/</code>, and extract everything after that prefix into a <code>__url</code> parameter to pass on to the script; the <code>QSA</code> flag means any GET parameters provided to the proxy will also be passed on.</p>
<p>Now we can address the other issue we ran into: the headers being lost on their way back. The cURL extension to PHP provides a <code>CURLOPT_HEADER</code> flag that can be set, which returns the headers associated with the response. Let's see how that might look:</p>
<samp>
 <h3>Second cut of our script</h3>
 <pre><kbd>define</kbd>(<var>'REMOTE_URL'</var>, <var>'https://their-end.io/api/'</var>);
<kbd>define</kbd>(<var>'OUR_URL'</var>, <var>'https://your-end.com/api-proxy/'</var>);

$params = $<kbd>_GET</kbd>;
<kbd>unset</kbd>($params[<var>'__url'</var>]);
$curl_params = [
  <s>// Include the requested endpoint</s>
  <var>CURLOPT_URL</var>            =&gt; (
    <var>REMOTE_URL</var> .
    $<kbd>_GET</kbd>[<var>'__url'</var>] .
    <var>'?'</var> .
    <kbd>http_build_query</kbd>($params)
  ),
  <var>CURLOPT_TIMEOUT</var>        =&gt; <var>30</var>,
  <var>CURLOPT_RETURNTRANSFER</var> =&gt; <var>true</var>,
  <var>CURLOPT_FOLLOWLOCATION</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYHOST</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYPEER</var> =&gt; <var>true</var>,
  <s>// Return the remote's headers</s>
  <var>CURLOPT_HEADER</var>         =&gt; <var>true</var>,
  <var>CURLOPT_CUSTOMREQUEST</var>  =&gt; $_SERVER[<var>'REQUEST_METHOD'</var>],
];

<s>// Anything with a POSTed body needs the body transferring</s>
<kbd>if</kbd> ($_SERVER[<var>'REQUEST_METHOD'</var>] !== <var>'GET'</var>) {
  $curl_params[<var>CURLOPT_POSTFIELDS</var>] = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
}

$c = <kbd>curl_init</kbd>();
<kbd>curl_setopt_array</kbd>($c, $curl_params);
$r = <kbd>curl_exec</kbd>($c);
<kbd>curl_close</kbd>($c);
<kbd>echo</kbd> $r;</pre>
 <h3>Output of the second run</h3>
 <pre>$ curl https://your-end.com/api-proxy/accounts
HTTP/1.1 401 Unauthorized
Set-Cookie: JSESSIONID=node0qrer3re8934rf0.node0
WWW-Authenticate: Basic realm="API: authentication required"
Cache-Control: must-revalidate,no-cache,no-store
Content-Type: text/html;charset=iso-8859-1
Content-Length: 58
Server: Jetty(9.4.48.v20220622)

&lt;html&gt;&lt;body&gt;
&lt;h1&gt;Error 401 Unauthorized&lt;/h1&gt;
&lt;/body&gt;&lt;/html&gt;</pre>
</samp>
<p>Progress! We've now received data from the correct remote URL, but we have the headers mixed in with the body in one returned block. The next step is to break out the headers and return those separately.</p>
<h2>Header extraction and provision</h2>
<p>Fortunately, the HTTP standard makes it fairly easy to programmatically spot where the headers stop and the response body starts. Headers are specified as ending with <code>\r\n</code> (that's carriage-return and new-line), and a blank header (two of these sequences in a row) is the marker for the end of the headers.</p>
<p>Once we have the headers as a block, we can use the fact that each ends with this newline sequence to output the headers as given:</p>
<samp>
 <h3>Header extraction and return</h3>
 <pre>$split_point = <kbd>strpos</kbd>($r, <var>"\r\n\r\n"</var>);
$headers = <kbd>trim</kbd>(<kbd>substr</kbd>($r, <var>0</var>, $split_point));
$body = <kbd>trim</kbd>(<kbd>substr</kbd>($r, $split_point));

<kbd>foreach</kbd>(<kbd>explode</kbd>(<var>"\r\n"</var>, $headers) <kbd>as</kbd> $h) {
  <kbd>header</kbd>($h);
}
<kbd>echo</kbd> $r;</pre>
 <h3>Output after header extraction</h3>
 <pre>$ curl -s -o /dev/null -w "%{http_code}\n" \
https://your-end.com/api-proxy/accounts
401</pre>
</samp>
<p>Now we're starting to see real results: a request that fails to authorise returns a 401. So let's pass in the credentials we were given by the remote API provider:</p>
<samp>
 <h3>Passing credentials to our proxy</h3>
 <pre>$ curl -s -o /dev/null -w "${http_code}\n" \
-u testuser:Passw0rd \
https://your-end.com/api-proxy/accounts
401</pre>
</samp>
<p>Error 401, "Authorization Required". Seems our credentials aren't being handed over to the remote; what's happening here is that our username and password are parsed out by the PHP proxy into server-side variables, which we then need to include in the request forwarded to the remote API.</p>
<p>Those server-side variables are <code>PHP_AUTH_USER</code> and <code>PHP_AUTH_PW</code>, and the HTTP specification states that those should be included in an <code>Authorization</code> header, but with a very particular format:</p>
<blockquote>
 <p>To receive authorization, the client
  <ol>
   <li>obtains the user-id and password from the user,</li>
   <li>constructs the user-pass by concatenating the user-id, a single
       colon (":") character, and the password,</li>
   <li>encodes the user-pass into an octet sequence (see below for a
       discussion of character encoding schemes),</li>
   <li>and obtains the basic-credentials by encoding this octet sequence
       using Base64 (RFC4648, Section 4) into a sequence of US-ASCII
       characters (RFC20).</li>
  </ol>
 <p>
 <p><em>-- RFC 7617, The 'Basic' HTTP Authentication Scheme</em></p>
</blockquote>
<p>As long as we follow this same scheme, the remote will have no trouble decoding the username and password we're proxying through. PHP's cURL extension allows us to provide custom headers alongside the request, though somewhat confusingly it uses <code>CURLOPT_HTTPHEADER</code> as the option for these headers (as opposed to <code>CURLOPT_HEADER</code> which we've already seen, and specifies that the <em>response</em> headers should be provided).</p>
<samp>
 <h3>Including credentials in the request</h3>
 <pre>$req_headers = [];
<kbd>if</kbd> (<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>], $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>])) {
  $req_headers[] = <var>'Authorization: Basic '</var> . <kbd>base64_encode</kbd>(
    $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>] . <var>':'</var> . $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>]
  );
}
<s>// ...</s>
$curl_params = [
  <s>// ...</s>
  <var>CURLOPT_HTTPHEADER</var>     =&gt; $req_headers,
];</pre>
 <h3>Trying out our credentials</h3>
 <pre>$ curl -u testuser:Passw0rd https://your-end.com/api-proxy/accounts | json_pp
{
   "count" : 1,
   "data" : [
      {
         "id" : "ec3ac5d4-34b6-4086-b88e-21eaff05b23b",
         "name" : "Testing Tester",
         "uri" : "https://their-end.io/api/accounts/ec3ac5d4-34b6-4086-b88e-21eaff05b23b"
      }
   ]
}</pre>
</samp>
<p>Oh goodness, a real return from our remote API. But there's something wrong...</p>
<h2>Content replacement and types</h2>
<p>We see from our <code>GET</code> request that there is one account record stored in the remote database, and the API provides a unique identifier to perform operations against the record in question. However, the identifier is a URI, and it points (understandably) to the remote's REST API: the one we're having to proxy in the first place.</p>
<p>Fortunately, this particular issue is fairly simple to resolve: as we have the full return string in <code>$body</code>, we just need to switch out any instances of the remote API's root URL with our own, and then we can try making some new requests to our proxied API:</p>
<samp>
 <h3>URL replacement in the output</h3>
 <pre>$split_point = <kbd>strpos</kbd>($r, <var>"\r\n\r\n"</var>);
$headers = <kbd>trim</kbd>(<kbd>substr</kbd>($r, <var>0</var>, $split_point));
$body = <kbd>trim</kbd>(<kbd>substr</kbd>($r, $split_point));
$body = <kbd>str_replace</kbd>(<var>REMOTE_URL</var>, <var>OUR_URL</var>, $body);

<kbd>foreach</kbd>(<kbd>explode</kbd>(<var>"\r\n"</var>, $headers) <kbd>as</kbd> $h) {
  <kbd>header</kbd>($h);
}
<kbd>echo</kbd> $r;</pre>
 <h3>Our final GET result</h3>
 <pre>$ curl -u testuser:Passw0rd https://your-end.com/api-proxy/accounts | json_pp
{
   "count" : 1,
   "data" : [
      {
         "id" : "ec3ac5d4-34b6-4086-b88e-21eaff05b23b",
         "name" : "Testing Tester",
         "uri" : "https://your-end.com/api-proxy/accounts/ec3ac5d4-34b6-4086-b88e-21eaff05b23b"
      }
   ]
}</pre>
 <h3>Proxying an update call</h3>
 <pre>$ curl -s -o /dev/null -w "%{http_code}\n" \
-H 'Content-Type: application/json' \
-X PUT -d '{"name":"A New Name"}' \
https://your-end.com/api-proxy/accounts/ec3ac5d4-34b6-4086-b88e-21eaff05b23b
415</pre>
</samp>
<p>Hold on, 415? That's "Unsupported media type", but we're providing a content type. As it turns out, the value of <code>Content-Type</code> provided to the proxy will need to be passed through to the cURL call if a POST or PUT is being made, or cURL will assume <code>text/plain</code>.</p>
<p>PHP receives this header as <code>CONTENT_TYPE</code>, so let's pull that in:</p>
<samp>
 <h3>Providing content type</h3>
 <pre>$req_headers = [];
<kbd>if</kbd> (<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>], $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>])) {
  $req_headers[] = <var>'Authorization: Basic '</var> . <kbd>base64_encode</kbd>(
    $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>] . <var>':'</var> . $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>]
  );
}
<kbd>if</kbd> (<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'CONTENT_TYPE'</var>])) {
  $req_headers[] = <var>'Content-Type: '</var> . $<kbd>_SERVER</kbd>[<var>'CONTENT_TYPE'</var>];
}</pre>
 <h3>Proxying an update, with the content type</h3>
 <pre>$ curl -s -o /dev/null -w "%{http_code}\n" \
-H 'Content-Type: application/json' \
-X PUT -d '{"name":"A New Name"}' \
https://your-end.com/api-proxy/accounts/ec3ac5d4-34b6-4086-b88e-21eaff05b23b
200</pre>
</samp>
<h2>Thanks for watching</h2>
<p>It lives! We can now proxy any call to the firewalled remote API, through a script we've hacked together in PHP, and it'll handle any part of the REST protocol. Along the way, we've learned a little about REST itself, authorisation headers in HTTP, and the various options and settings that can be given to cURL calls in PHP.</p>
<p>This post has been an experiment with a "slow-roll livecoding" format, where a live coding session is written out in sanitised long form. I think this was fun, we might do it again sometime. For reference, here's the final proxy script we came up with:</p>
<samp>
 <pre><kbd>define</kbd>(<var>'REMOTE_URL'</var>, <var>'https://their-end.io/api/'</var>);
<kbd>define</kbd>(<var>'OUR_URL'</var>, <var>'https://your-end.com/api-proxy/'</var>);

$req_headers = [];
<kbd>if</kbd> (<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>], $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>])) {
  $req_headers[] = <var>'Authorization: Basic '</var> . <kbd>base64_encode</kbd>(
    $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_USER'</var>] . <var>':'</var> . $<kbd>_SERVER</kbd>[<var>'PHP_AUTH_PW'</var>]
  );
}
<kbd>if</kbd> (<kbd>isset</kbd>($<kbd>_SERVER</kbd>[<var>'CONTENT_TYPE'</var>])) {
  $req_headers[] = <var>'Content-Type: '</var> . $<kbd>_SERVER</kbd>[<var>'CONTENT_TYPE'</var>];
}

$params = $<kbd>_GET</kbd>;
<kbd>unset</kbd>($params[<var>'__url'</var>]);
$curl_params = [
  <var>CURLOPT_URL</var>            =&gt; (
    <var>REMOTE_URL</var> .
    $<kbd>_GET</kbd>[<var>'__url'</var>] .
    <var>'?'</var> .
    <kbd>http_build_query</kbd>($params)
  ),
  <var>CURLOPT_TIMEOUT</var>        =&gt; <var>30</var>,
  <var>CURLOPT_RETURNTRANSFER</var> =&gt; <var>true</var>,
  <var>CURLOPT_FOLLOWLOCATION</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYHOST</var> =&gt; <var>true</var>,
  <var>CURLOPT_SSL_VERIFYPEER</var> =&gt; <var>true</var>,
  <var>CURLOPT_HEADER</var>         =&gt; <var>true</var>,
  <var>CURLOPT_HTTPHEADER</var>     =&gt; $req_headers,
  <var>CURLOPT_CUSTOMREQUEST</var>  =&gt; $_SERVER[<var>'REQUEST_METHOD'</var>],
];

<kbd>if</kbd> ($_SERVER[<var>'REQUEST_METHOD'</var>] !== <var>'GET'</var>) {
  $curl_params[<var>CURLOPT_POSTFIELDS</var>] = <kbd>file_get_contents</kbd>(<var>'php://input'</var>);
}

$c = <kbd>curl_init</kbd>();
<kbd>curl_setopt_array</kbd>($c, $curl_params);
$r = <kbd>curl_exec</kbd>($c);
<kbd>curl_close</kbd>($c);

$split_point = <kbd>strpos</kbd>($r, <var>"\r\n\r\n"</var>);
$headers = <kbd>trim</kbd>(<kbd>substr</kbd>($r, <var>0</var>, $split_point));
$body = <kbd>trim</kbd>(<kbd>substr</kbd>($r, $split_point));
$body = <kbd>str_replace</kbd>(<var>REMOTE_URL</var>, <var>OUR_URL</var>, $body);

<kbd>foreach</kbd>(<kbd>explode</kbd>(<var>"\r\n"</var>, $headers) <kbd>as</kbd> $h) {
  <kbd>header</kbd>($h);
}
<kbd>echo</kbd> $r;</pre>
</samp>
 ]]></content>
</entry>
<entry>
 <title type="html">Building a Solitaire &quot;AI&quot; in JavaScript</title>
 <link href="https://imrannazar.com/articles/solitaire-ai-js" rel="alternate" type="text/html" title="Building a Solitaire &quot;AI&quot; in JavaScript" />
 <id>https://imrannazar.com/articles/solitaire-ai-js</id>
 <summary>Ever wondered if it&#039;s possible to automatically solve a game of Solitaire? It&#039;s something I got to thinking about a little while ago, and this article looks into one way you could go about it.</summary>
 <category term="Articles" />
 <published>Sat, 02 Mar 2024 16:30:57 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Every now and then I'll get a few minutes' downtime, and I'll turn to something which lets me pass the time. Most recently, that's been a quick game of online Klondike Solitaire, the classic card game; it usually takes no more than five minutes to either solve the random game that's served up, or to work out that there's probably no solution.</p>
<p>I generally use Solitaired's implementation of the game, and one thing in particular caught my eye while looking at the new-game menu:</p>
<figure>
 <img src="/content/img/solitaire-js-newgame.png" alt="New game menu on Solitaired">
 <figcaption>Figure 1: Solitaired's New-Game menu</figcaption>
</figure>
<p>On this menu is a "winnable only" option, whereby the game served is known to be a shuffle of the deck that, when dealt out, definitely has at least one path to solution. The inevitable question arises:</p>
<h2>How Can We Know A Game Is Winnable?</h2>
<p>As it turns out, there's no formula for determining whether a given shuffle is solvable: what we'll need to do here is build a solver that can search through all the possible moves, until it runs into a state where the game has been won and all the cards are stacked up in their end positions.</p>
<p>Let's take the following initial deal-out:</p>
<figure>
 <img src="/content/img/solitaire-js-first.png" alt="Initial state of a game of Solitaire">
 <figcaption>Figure 2: Initial state of a game of Solitaire</figcaption>
</figure>
<p>From top-left on the game board, we have:
 <ul>
  <li>The "stock" of cards yet to be dealt, face-down;</li>
  <li>The "waste" pile onto which cards are put when pulled from the top of the stock;</li>
  <li>The "foundations" which act as the end positions for the four suits, stacked in order;</li>
  <li>The "tableaus" which are initially dealt out with a number of cards corresponding to their position on the board (one to seven).</li>
 </ul>
</p>
<p><em>Other variants of Solitaire exist, but as we're dealing with Klondike here, we can hard-code various things like the number of cards to shuffle, and the number of tableaus.</em></p>
<p>When we say "build a solver", what we're looking to do is take an initial deal-out of a shuffled deck like the above, and apply those moves which are both:
 <ul>
  <li><strong>Valid</strong> moves in Solitaire: This is the list of all moves that could be made under the game rules;</li>
  <li><strong>Eligible</strong> given the state of the board: This means each of the valid moves needs to filter validity against the current state of the game.</li>
 </ul>
</p>
<p>The plan is to apply one of the eligible valid moves to the game board, see where the board ends up, and apply a move which has now become valid and eligible; we keep doing this until our path runs out and we have no more available moves. If the game hasn't been solved at this point (if, in other words, we don't have the suits all stacked up in the foundations), we need to backtrack up the path of moves and make another eligible and valid move from the point at which we have the option available.</p>
<p>If we take Figure 2, and work out those moves which are both valid and eligible, we may end up with a tree of moves that looks something like this:</p>
<figure class="invertable">
 <img src="/content/img/solitaire-js-dfs.png" alt="Top levels of a DFS tree">
 <figcaption>Figure 3: The first couple of levels of a search tree</figcaption>
</figure>
<p>The more algorithmically astute reader will recognise this as a description of <em>depth-first search</em> (DFS), a process whereby a tree of things (in this case, game states) can be searched through for some criterion. In the general case, <em>breadth-first search</em> tends to be used if one is looking for the most optimal match; for our solver, that would mean the least number of moves to a winning state. For our purposes though, as we're just looking to see whether the game can be solved at all, we can use the simpler DFS algorithm.</p>
<h2>Representing a Solitaire game board</h2>
<p>So we'll need to populate the nodes of this tree with representations of game states, starting with the initial deal-out as the first node. It quickly becomes obvious that the first thing we need is not, in fact, a representation of the board: it's a representation of a <em>card</em> which we can then use to build the board. Our "card" needs three things: suit (one of four), rank (one of thirteen), and whether the card in question is face-up on the board. This lends itself well to a bitfield:</p>
<figure>
 <pre>    7        6         5    4      3  2  1  0
+-------+----------+-------------+------------+
| Empty | Face-up  | Suit        | Rank       |
+-------+----------+-------------+------------+
|       | 0 = Down | 0 = Ace     | 0 = Unused |
|       | 1 = Up   | 1 = Heart   | 1 = Ace    |
|       |          | 2 = Club    | ...        |
|       |          | 3 = Diamond | 13 = King  |
+-------+----------+-------------+------------+</pre>
 <figcaption>Figure 4: Bitfield layout for playing card data</figcaption>
</figure>
<p>Our state representation then becomes an object containing arrays of numbers, where each of the numbers conforms to this bitfield format for a card:</p>
<samp>
 <h3>Board state for Figure 2</h3>
 <pre>{
  <var>"stock"</var>: [
    <var>4</var>,<var>45</var>,<var>24</var>,<var>12</var>,<var>35</var>,<var>41</var>,<var>29</var>,<var>57</var>,<var>36</var>,<var>37</var>,<var>6</var>,<var>34</var>,<var>23</var>,<var>17</var>,<var>38</var>,<var>2</var>,<var>28</var>,<var>53</var>,<var>51</var>,<var>40</var>,<var>50</var>,<var>59</var>,<var>21</var>,<var>60</var>
  ],
  <var>"waste"</var>: [],
  <var>"foundations"</var>: [
    [],    <s>// Aces</s>
    [],    <s>// Hearts</s>
    [],    <s>// Clubs</s>
    []     <s>// Diamonds</s>
  ],
  <var>"tableaus"</var>: [
    [<var>107</var>],
    [<var>54</var>,<var>69]</var>,
    [<var>58</var>,<var>55</var>,<var>77</var>],
    [<var>19</var>,<var>27</var>,<var>18</var>,<var>116</var>],
    [<var>10</var>,<var>8</var>,<var>56</var>,<var>20</var>,<var>106</var>],
    [<var>3</var>,<var>9</var>,<var>61</var>,<var>7</var>,<var>44</var>,<var>86</var>],
    [<var>49</var>,<var>1</var>,<var>11</var>,<var>33</var>,<var>25</var>,<var>39</var>,<var>90</var>]
  ]
}</pre>
</samp>
<p>And moves on the board become changes in this state representation. If we're going to deal with a lot of these state changes, we're going to need a way to visualise what's happening (or at least, I needed a visual way to make sense of things)...</p>
<h2>Rendering a Solitaire game board</h2>
<p>As this is a JavaScript adventure, we may's well render the game board using JS. There are a few ways one could go about this: drawing card graphics to a canvas perhaps, or using some virtual-DOM framework to build <code>Card</code> components which can be combined with business logic at some higher level.</p>
<p>That seems a bit much, though. For our purposes, we can get away with building the game board out in HTML, and re-rendering the whole page whenever a move is made. Let's start once again with the individual cards, for which there are complete sets of open-source SVGs online:</p>
<samp>
 <h3>HTML sample for an individual playing card</h3>
 <pre>&lt;<kbd>span</kbd> class=<var>"card s2"</var>&gt;2 of Spades&lt;/<kbd>span</kbd>&gt;</pre>
 <h3>CSS for the above playing card</h3>
 <pre>.card {
  <kbd>display</kbd>: <kbd>block</kbd>;
  <kbd>overflow</kbd>: <kbd>hidden</kbd>;
  <kbd>text-indent</kbd>: <var>-9999px</var>;
  <kbd>height</kbd>: <var>163px</var>;
  <kbd>width</kbd>: <var>112px</var>;
  <kbd>border</kbd>: <var>1px</var> <kbd>solid</kbd> <var>black</var>;
  <kbd>border-radius</kbd>: <var>4px</var>;
  <kbd>background-repeat</kbd>: <kbd>no-repeat</kbd>;
  <kbd>background-position</kbd>: <var>center center</var>;
  <kbd>background-size</kbd>: <kbd>cover</kbd>;
}
.s1 { <kbd>background-image</kbd>: <kbd>url</kbd>(<var>ace_of_spades.svg</var>); }
.s2 { <kbd>background-image</kbd>: <kbd>url</kbd>(<var>2_of_spades.svg</var>); }
<s>/* ...
   48 card backgrounds omitted
   ... */</s>
.d12 { <kbd>background-image</kbd>: <kbd>url</kbd>(<var>queen_of_diamonds.svg</var>); }
.d13 { <kbd>background-image</kbd>: <kbd>url</kbd>(<var>king_of_diamonds.svg</var>); }
.facedown { <kbd>background-image</kbd>: <kbd>url</kbd>(<var>cardback.svg</var>); }</pre>
</samp>
<p>For this project, I've used the <code>simple</code> set of SVGs from <a href="https://github.com/hayeah/playing-cards-assets">hayeah's playing-cards-assets</a> for the card fronts, and <a href="https://commons.wikimedia.org/wiki/File:Atlas_deck_card_back_blue_and_brown.svg">Dmitry Fomin's SVG on Wikidata</a> for the card back.</p>
<p>Our JavaScript for the card renderer doesn't need to be all that complicated either, as we can build HTML directly as a string:</p>
<samp>
 <h3>JS card rendering class</h3>
 <pre><kbd>const</kbd> Card = {
  SUIT_CLASS: [<var>'s'</var>, <var>'h'</var>, <var>'c'</var>, <var>'d'</var>],
  SUIT_NAMES: [<var>'Spades'</var>, <var>'Hearts'</var>, <var>'Clubs'</var>, <var>'Diamonds'</var>],
  RANK_NAMES: [
    <var>'Ace'</var>, <var>2</var>, <var>3</var>, <var>4</var>, <var>5</var>, <var>6</var>, <var>7</var>, <var>8</var>, <var>9</var>, <var>10</var>, <var>'Jack'</var>, <var>'Queen'</var>, <var>'King'</var>
  ],
  toClassName: c =&gt; <var>`${</var>Card.SUIT_CLASS[(c &gt;&gt; <var>4</var>) &amp; <var>3</var>]<var>}${</var>(c &amp; <var>15</var>)<var>}`</var>,
  toString: c =&gt; (
    Card.RANK_NAMES[c &amp; <var>15</var>] +
    <var>' of '</var> +
    Card.SUIT_NAMES[(c &gt;&gt; <var>4</var>) &amp; <var>3</var>]
  ),
  render: c =&gt; [
    <var>'&lt;span class="card '</var>,
    (c &amp; <var>0x40</var>) ? Card.toClassName(c) : <var>'facedown'</var>,
    <var>'"&gt;'</var>,
    Card.toString(c),
    <var>'&lt;/span&gt;'</var>
  ].<kbd>join</kbd>('')
};
<kbd>document</kbd>.innerHTML = Card.render(<var>0x42</var>); <s>// 2 of spades, face-up</s></pre>
</samp>
<p>The above code nets us something that looks like this:</p>
<figure>
 <img src="/content/img/solitaire-js-s2.png" alt="The 2 of spades">
 <figcaption>Figure 5: The 2 of spades, as rendered by our JS</figcaption>
</figure>
<p>From here, the individual regions of the board can be rendered as cards or lists of cards. For simplicity, we can treat regions where one card is visible as lists containing one card:</p>
<samp>
 <h3>HTML for the playing field</h3>
 <pre>&lt;<kbd>body</kbd>&gt;
 &lt;<kbd>main</kbd> id=<var>"field"</var>&gt;
  &lt;<kbd>ul</kbd> id=<var>"stock"</var>&gt;&lt;/</kbd>ul&gt;
  &lt;<kbd>ul</kbd> id=<var>"waste"</var>&gt;&lt;/</kbd>ul&gt;
  &lt;<kbd>ul</kbd> id=<var>"foundations"</var>&gt;&lt;/</kbd>ul&gt;
  &lt;<kbd>ul</kbd> id=<var>"tableaus"</var>&gt;
    &lt;<kbd>li</kbd> id=<var>"tableau-0"</var>&gt;
      &lt;<kbd>ol</kbd>&gt;&lt;/<kbd>ol</kbd>&gt;
    &lt;/<kbd>li</kbd>&gt;
    &lt;<s>!-- And the other tableaus... --&gt;</s>
    &lt;<kbd>li</kbd> id=<var>"tableau-6"</var>&gt;
      &lt;<kbd>ol</kbd>&gt;&lt;/<kbd>ol</kbd>&gt;
    &lt;/<kbd>li</kbd>&gt;
  &lt;/<kbd>ul</kbd>&gt;
 &lt;/<kbd>main</kbd>&gt;
&lt;/<kbd>body</kbd>&gt;</pre>
 <h3>Grid CSS for the playing field</h3>
 <pre>:<kbd>root</kbd> {
  --card-width: <var>112px</var>;
  --card-height: <var>163px</var>;
  --card-stack-gap: <var>40px</var>;
}
<kbd>body</kbd> {
  <kbd>background</kbd>: <var>green</var>;
}
#field {
  <kbd>display</kbd>: <kbd>grid</kbd>;
  <kbd>grid-template-areas</kbd>:
    <var>"stock waste foundations"
    "tableaus tableaus tableaus"</var>;
  <kbd>grid-template-columns</kbd>: <kbd>var</kbd>(<var>--card-width</var>) <kbd>var</kbd>(<var>--card-width</var>) <var>1fr</var>;
  <kbd>grid-template-rows</kbd>: <kbd>var</kbd>(<var>--card-height</var>) <var>1fr</var>;
  <kbd>gap</kbd>: <var>32px</var>;
}
<kbd>ul</kbd>, <kbd>ol</kbd> {
  <kbd>list-style</kbd>: <var>none inside</var>;
}
#stock { <kbd>grid-area</kbd>: <var>stock</var>; }
#waste { <kbd>grid-area</kbd>: <var>waste</var>; }
#foundations {
  <kbd>grid-area</kbd>: <var>foundations</var>;
  <kbd>display</kbd>: <kbd>flex</kbd>;
  <kbd>gap</kbd>: <var>32px</var>;
  <kbd>justify-content</kbd>: <kbd>flex-end</kbd>;
}
#tableaus {
  <kbd>grid-area</kbd>: <var>tableaus</var>;
  <kbd>display</kbd>: <kbd>flex</kbd>;
  <kbd>justify-content</kbd>: <kbd>space-between</kbd>;
  <kbd>gap</kbd>: <var>32px</var>;
}
#tableaus &gt; <kbd>li</kbd> {
  <kbd>width</kbd>: <kbd>var</kbd>(<var>--card-width</var>);
}
#tableaus <kbd>ol</kbd> {
  <kbd>position</kbd>: <kbd>relative</kbd>;
  <kbd>width</kbd>: <kbd>var</kbd>(<var>--card-width</var>);
}
#tableaus <kbd>ol</kbd> <kbd>li</kbd> {
  <kbd>position</kbd>: <kbd>absolute</kbd>;
}
<kbd>li</kbd>:nth-child(<var>2</var>) { <kbd>top</kbd>: <kbd>calc</kbd>(<kbd>var</kbd>(<var>--card-stack-gap</var>) * <var>1</var>); }
<kbd>li</kbd>:nth-child(<var>3</var>) { <kbd>top</kbd>: <kbd>calc</kbd>(<kbd>var</kbd>(<var>--card-stack-gap</var>) * <var>2</var>); }
<s>/* ...
   If the last tableau has a King face-up card initially,
   we can have up to 19 cards in a tableau
   ... */</s>
<kbd>li</kbd>:nth-child(<var>18</var>) { <kbd>top</kbd>: <kbd>calc</kbd>(<kbd>var</kbd>(<var>--card-stack-gap</var>) * <var>17</var>); }
<kbd>li</kbd>:nth-child(<var>19</var>) { <kbd>top</kbd>: <kbd>calc</kbd>(<kbd>var</kbd>(<var>--card-stack-gap</var>) * <var>18</var>); }</pre>
</samp>
<p>And the final piece of the puzzle is to shuffle a deck of cards into a representation of the initial game state, and fill in the above list elements. Those'll be two separate functions: let's have a look at the shuffle first.</p>
<p>A full deck of playing cards is 52 cards, but we have two considerations to make:
 <ul>
  <li><strong>Format</strong>: Our internal representation of a playing card is a bitfield, so we can't use the numbers 1 to 52 (or indeed, 0 to 51); we'll need instead to build an array of values conforming to the bitfield.</li>
  <li><strong>Library</strong>: Languages such as PHP offer an <code>array_shuffle</code> library function to randomise an array, but JavaScript's standard library is lacking in this regard. We'll need a scrap of custom shuffling code to do the trick.</li>
 </ul>
</p>
<p>The magic is served in the form of <code>Array.splice</code>, which does all the things we need: extract a chunk out of an array, splice the two ends back together, and return the extracted chunk. Importantly, the splicing happens in-place; if we have an array of ten elements, and perform <code>splice(5, 1)</code>, the array is now nine elements long, and what used to be the element at index 5 is extracted.</p>
<p>With that, we have everything we need to build up the initial state:</p>
<samp>
 <h3>JS to generate an initial game state</h3>
 <pre><kbd>const</kbd> Solitaire = {
  init: () =&gt; {
    <s>// Build up a deck of cards in our bitfield format</s>
    <kbd>let</kbd> deck = [], shuffled = [];
    <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &lt; <var>4</var>; i++) {
      <kbd>for</kbd> (<kbd>let</kbd> j = <var>1</var>; j &lt;= <var>13</var>; j++) {
        deck.<kbd>push</kbd>(i &lt;&lt; <var>4</var> | j);
      }
    }

    <s>// Pull random cards out of the deck until we run out</s>
    <kbd>do</kbd> {
      shuffled.<kbd>push</kbd>(deck.<kbd>splice</kbd>(
        <var>0</var> | (<kbd>Math</kbd>.<kbd>random</kbd>() * deck.<kbd>length</kbd>), <var>1</var>
      )[<var>0</var>]);
    } <kbd>while</kbd> (deck.<kbd>length</kbd> &gt; <var>0</var>);

    <s>// Deal out the tableaus, drop what's left in the stock</s>
    <kbd>const</kbd> state = {
      stock: [],
      waste: [],
      foundations: [[], [], [], []],
      tableaus: [[], [], [], [], [], [], []],
    };
    state.tableaus.<kbd>forEach</kbd>((tb, idx) =&gt; {
      <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &gt;= idx; i++) {
        state.tableaus[idx].<kbd>push</kbd>(shuffled.<kbd>pop</kbd>());
      }
      <s>// Face-up the last card</s>
      state.tableaus[idx][state.tableaus[idx].length - <var>1</var>] |= <var>0x40</var>;
    });
    state.stock = [...shuffled];

    Solitaire.render(state);
  },
  render: (state) =&gt; {
    <s>// TODO</s>
  },
};
<kbd>window</kbd>.<kbd>onload</kbd> = <kbd>function</kbd>() { Solitaire.init(); }</pre>
</samp>
<p>Rendering the board is a simple case of building HTML for each of the regions on the board, filling in the cards as list items. One caveat is that the tableaus can be empty, but the other regions still need to be visible even if no cards are present; for this, we can render an empty item with the <code>card</code> class but no specific background.</p>
<samp>
 <h3>JS to render the game board</h3>
 <pre>render: (state) =&gt; {
  <kbd>const</kbd> emptyCard = <var>'&lt;li class="card"&gt;&lt;/li&gt;'</var>;
  <kbd>document</kbd>.getElementById(<var>'stock'</var>).innerHTML =
    state.stock.<kbd>length</kbd> &gt; <var>0</var>
      ? Card.render(state.stock[state.stock.<kbd>length</kbd> - <var>1</var>])
      : emptyCard;

  <kbd>document</kbd>.getElementById(<var>'waste'</var>).innerHTML =
    state.waste.<kbd>length</kbd> &gt; <var>0</var>
      ? Card.render(state.waste[state.waste.<kbd>length</kbd> - <var>1</var>])
      : emptyCard;

  <kbd>document</kbd>.getElementById(<var>'foundations'</var>).innerHTML = 
    state.foundations.<kbd>map</kbd>(f =&gt; (f.<kbd>length</kbd> &gt; <var>0</var>
      ? Card.render(f[f.<kbd>length</kbd> - <var>1</var>])
      : emptyCard
    )).<kbd>join</kbd>(<var>''</var>);

  <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &lt; <var>7</var>; i++) {
    <kbd>document</kbd>.getElementById(`tableau-${i}`).innerHTML = [
      <var>'&lt;ol&gt;'</var>,
      ...(state.tableaus[i].<kbd>map</kbd>(t =&gt; Card.render(t))),
      <var>'&lt;/ol&gt;'</var>,
    ].<kbd>join</kbd>(<var>''</var>);
  }
},</pre>
</samp>
<h2>Building the solver</h2>
<p>Now we can see the Solitaire game board, we can visualise moves made towards solving a game. As mentioned above, each node in the tree of moves takes a game state and applies one of the <em>eligible</em> and <em>valid</em> moves.</p>
<p>Valid moves are those available to us under the game rules. In order of preference:
 <ul>
  <li><strong>Waste to foundation</strong>: A card can go directly from the drawn waste pile to the suit's foundation, if it's already populated up to one rank below this card.</li>
  <li><strong>Top of a tableau to foundation</strong>: For each tableau, the last face-up card can move to its suit's foundation if that foundation is already populated.</li>
  <li><strong>King-stack to an empty tableau</strong>: Kings can only be placed on empty tableaus; for each tableau, if the face-up stack has a King at the bottom, and an empty tableau exists, moving the stack is valid.</li>
  <li><strong>Non-king stack to eligible tableau</strong>: For each tableau, any stack (or substack) of face-up cards on tableau A can move to another tableau B if the bottom card on A's substack is of an <em>opposite-coloured</em> suit to the top of B, AND one rank lower.</li>
  <li><strong>King waste to empty tableau</strong>: If a King was just drawn, and an empty tableau exists, it can be placed therein.</li>
  <li><strong>Non-king waste to eligible tableau</strong>: For each tableau, if the just-drawn top of waste is of an <em>opposite-coloured</em> suit to the top of the tableau, AND one rank lower, it can be placed at the top of the tableau.</li>
  <li><strong>Draw</strong>: If the stock has cards, pull a card from the stock, face it up and put it atop the waste.</li>
  <li><strong>Reset</strong>: If the stock has no cards and the waste has cards, face-down all the waste cards and reverse their order, putting them back into the stock.</li>
 </ul>
</p>
<p>For each of these, we'll need a function that generates the next state in the game, given a state representation. In the interests of brevity, I won't include all the move implementations here; a flavour of them can be seen from the sample below, of one of the more complex cases.</p>
<samp>
 <h3>Next-move handlers, with one example</h3>
 <pre><kbd>const</kbd> end = (a) =&gt; a[a.<kbd>length</kbd> - <var>1</var>];
<kbd>const</kbd> Card = {
  ...
  rank: (c) =&gt; c &amp; <var>15</var>,
  suit: (c) =&gt; (c &gt;&gt; <var>4</var>) &amp; <var>3</var>,
  areOpposite: (c, d) =&gt; (c &amp; <var>16</var>) ^ (d &amp; <var>16</var>),
  isFaceUp: (c) =&gt; !!(c &amp; <var>64</var>)
};
<kbd>const</kbd> Solitaire = {
  ...
  moves: [
    ...
    <s>// King stack to empty tableau</s>
    (stateJson) =&gt; {
      <kbd>const</kbd> nextStates = [];
      <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &lt; <var>7</var>; i++) {
        <kbd>const</kbd> state = <kbd>JSON</kbd>.<kbd>parse</kbd>(stateJson);

        <s>// If there's more than one card on this tableau, AND
        // the first face-up card is a King, AND
        // there's an empty tableau to move the stack to, AND
        // we'd be left with at least one card after moving</s>

        <kbd>if</kbd> (state.tableaus[i].<kbd>length</kbd> &gt; <var>1</var>) {
          <kbd>if</kbd> (!Card.isFaceUp(state.tableaus[i][<var>0</var>])) {
            <kbd>if</kbd> (
              Card.rank(
                state.tableaus[i].<kbd>filter</kbd>(c =&gt; c &amp; <var>64</var>)[<var>0</var>]
              ) === <var>13</var>
            ) {
              <s>// There may be multiple empty tableaus
              // Moving to each is separately valid</s>
              <kbd>for</kbd> (<kbd>let</kbd> j = <var>0</var>; j &lt; <var>7</var>; j++) {
                <kbd>if</kbd> (state.tableaus[j].<kbd>length</kbd> === <var>0</var>) {
                  <s>// Pop the face-up cards off tableau i into j</s>
                  <kbd>while</kbd> (end(state.tableaus[i]) &amp; <var>64</var>) {
                    state.tableaus[j].<kbd>push</kbd>(
                      state.tableaus[i].<kbd>pop</kbd>()
                    );
                  }
                  <s>// j is now backwards</s>
                  state.tableaus[j].<kbd>reverse</kbd>();

                  <s>// Face-up the top card left behind</s>
                  state.tableaus[i][state.tableaus[i].<kbd>length</kbd> - <var>1</var>] |= <var>64</var>;
                  <s>// Record this as a valid next state</s>
                  nextStates.<kbd>push</kbd>(state);
                  <kbd>break</kbd>;
                }
              }
            }
          }
        }
      }
      <kbd>return</kbd> nextStates;
    }
  ],
};</pre>
</samp>
<p>Those with an eye for detail will note that the move handlers are receiving a JSON string representing the game state. The search algorithm itself calls for this, as our DFS solver implementation will determine the next state as follows:
 <ul>
  <li>If this state represents a full set of foundations, we can stop;</li>
  <li>If we've been going for long enough that there's probably no solution, we can stop;</li>
  <li>Otherwise, render this state on screen;</li>
  <li>Call the move handlers in turn, and build an array of valid next states;</li>
  <li>For each valid next state, <em>if we haven't already seen it</em>, recurse.</li>
 </ul>
</p>
<p>We can satisfy the "already seen it" clause here by calculating a hash of each game state as it's generated, and storing it in a list; if a game state is generated by our next-move handlers whereby its hash is already in this list, we won't need to recurse into it another time, thus limiting the search space.</p>
<p>Recent browser implementations of JavaScript offer the <code>crypto</code> service which exposes various hashing functions that run at native speed, so we won't need to worry overly about performance:</p>
<samp>
 <h3>DFS and hash list implementation</h3>
 <pre><kbd>const</kbd> sha256 = <kbd>async</kbd> (state) =&gt; {
  <kbd>const</kbd> msg = <kbd>new</kbd> TextEncoder(<var>'utf-8'</var>).encode(<kbd>JSON</kbd>.<kbd>stringify</kbd>(state));
  <kbd>const</kbd> buf = <kbd>await</kbd> <kbd>window</kbd>.<kbd>crypto</kbd>.subtle.digest(<var>'SHA-256'</var>, msg);
  <kbd>const</kbd> arr = <kbd>Array</kbd>.<kbd>from</kbd>(<kbd>new</kbd> Uint8Array(buf));
  <kbd>return</kbd> arr.<kbd>map</kbd>(b =&gt; (<var>'00'</var> + b.toString(<var>16</var>)).slice(<var>-2</var>)).join(<var>''</var>);
};
<kbd>const</kbd> Solitaire = {
  ...
  isSearching: <var>true</var>,
  isWinnable: <var>false</var>,
  visitedMoves: [],
  MAX_MOVES: <var>50000</var>,

  next: <kbd>async</kbd> (state) =&gt; {
    <kbd>const</kbd> hash = <kbd>await</kbd> sha256(state);
    Solitaire.visitedMoves.<kbd>push</kbd>(hash);

    <s>// If all the cards are in the foundations,
    // assume they're in order and we've won</s>
    <kbd>if</kbd> (state.foundations.<kbd>filter</kbd>(
      f =&gt; f.<kbd>length</kbd> === <var>13</var>
    ).<kbd>length</kbd> === <var>4</var>) {
      Solitaire.isSearching = <var>false</var>;
      Solitaire.isWinnable = <var>true</var>;
      Solitaire.render(state);
    }

    <s>// If we've been going for ...a while,
    // assume we won't be going to space today</s>
    <kbd>if</kbd> (Solitaire.visitedMoves.<kbd>length</kbd> &gt; Solitaire.MAX_MOVES) {
      Solitaire.isSearching = <var>false</var>;
      Solitaire.isWinnable = <var>false</var>;
      Solitaire.render(state);
    }

    <s>// Otherwise we're still going</s>
    <kbd>if</kbd> (Solitaire.isSearching) {
      Solitaire.render(state);
      
      <s>// Collect all the eligible moves</s>
      <kbd>let</kbd> eligibleMoves = [], newMoves = [];
      Solitaire.moves.<kbd>forEach</kbd>((move) =&gt; {
        eligibleMoves = eligibleMoves.<kbd>concat</kbd>(
          move(<kbd>JSON</kbd>.<kbd>stringify</kbd>(state))
        );
      });

      <s>// Filter for those we haven't seen before</s>
      <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &gt; eligibleMoves.<kbd>length</kbd>; i++) {
        <kbd>const</kbd> newHash = <kbd>await</kbd> sha256(eligibleMoves[i]);
        if (!Solitaire.visitedMoves.<kbd>includes</kbd>(newHash)) {
          newMoves.<kbd>push</kbd>(eligibleMoves[i]);
        }
      }

      <s>// Dig a little deeper</s>
      <kbd>for</kbd> (<kbd>let</kbd> i = <var>0</var>; i &lt; newMoves.<kbd>length</kbd>; i++) {
        <kbd>await</kbd> Solitaire.next(newMoves[i]);
      }
    }
  }
};</pre>
</samp>
<p>And if we've done everything correctly, with a bit of luck from the random number generator, we'll find a shuffle that can be won:</p>
<figure>
 <video controls loop muted preload="auto">
  <source type="video/mp4" src="/content/img/solitaire-js-find.mp4">
 </video>
 <figcaption>Figure 6: An example of finding a game's winning path</figcaption>
</figure>
<h2>Next steps</h2>
<p>So we've answered, to an extent at least, the question of how to determine that a game of Solitaire is winnable. There are a few things that come to mind once we see this solver working:</p>
<dl>
 <dt>Minimal search path</dt>
 <dd>Figure 6 above shows a path to solution of over 400 moves, whereas it's rare to see a winnable game of Solitaire that edges past 150. This is likely because our solver finds the <em>first</em> path to a winning state, and not necessarily the <em>best</em> path.</dd>
 <dd>Implementations of breadth-first search for solving Solitaire are out there, an example being <a href="https://github.com/ShootMe/MinimalKlondike">ShootMe's MinimalKlondike</a> which is a command-line solver written in C#. It's not beyond the realm of possibility to rewrite <code>Solitaire.next</code> in our code to use BFS in this fashion.</dd>
 <dt>Custom shuffles</dt>
 <dd>It's somewhat limiting to have the solver generate a shuffle at random, and determine whether that shuffle is solvable; it would be nice to have the solver accept a shuffled deck in some format, and use that as its source for the initial deal-out and solve.</dd>
 <dd>There doesn't seem to be a standard format for this, unfortunately; ShootMe's solver linked above takes its shuffle sources in a file format "from an old web site", but no further detail is given on whether that format is widely used.</dd>
 <dt>Playability</dt>
 <dd>If one were so inclined, this could be the start of an implementation of Solitaire: each of the cards rendered on the page is a HTML element, which could (with some supporting code) be dragged and dropped into an eligible spot on the game board.</dd>
 <dd>We may even be able to introduce a "Winnable only" option on the New Game button, as per Figure 1, the thing that sparked off this whole mess.</dd>
</dl>
<p>There's scope for expansion here, but I won't promise a part two of this article; I've been caught out by doing that before. Instead, I'll leave the code for the solver as it stands:</p>
<p><a href="https://github.com/Two9A/solitaire-js">solitaire-js: A solver for Klondike Solitaire</a></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Wildcard Email Addresses with Self-Hosted Postfix</title>
 <link href="https://imrannazar.com/hacks/wildcard-email-with-postfix" rel="alternate" type="text/html" title="Wildcard Email Addresses with Self-Hosted Postfix" />
 <id>https://imrannazar.com/hacks/wildcard-email-with-postfix</id>
 <summary>I&#039;ve found it very useful over the years to be able to receive email to any address at my domain. This is a quick look at how Postfix can be configured to provide routing for wildcard addresses, so it all lands in the same inbox.</summary>
 <category term="Quick Hacks" />
 <published>Sat, 03 Feb 2024 13:30:07 +0000</published>
 <content type="text/html"><![CDATA[
   <p>If you've ever received spam to your email (and if you've had an email address for more than ten minutes, you've had spam) it can be difficult to find out how the spammers got hold of your address. If you have a domain name of your own, some interesting tools open up that can help to determine the provenance of spam, and from where the spammers get their databases; the tool this article covers is wildcard email addresses.</p>
<p>For example, <em>many</em> years ago I signed up to TV Tropes (probably to post a comment on some trope page). At some point, TV Tropes suffered a data breach and their user database was lifted, including email addresses, which means to this day I get emails like the following:</p>
<samp>
 <pre>From: "Equipe RH" &lt;rfgfx@[redacted]&gt;
To: &lt;tropes@imrannazar.com&gt;
Subject: I RECORDED YOU!
Date: Thu, 13 Oct 2023 15:27:47 +0330

Hello there!

Unfortunately, there are some bad news for you.

Some time ago your device was infected with my private trojan,
R.A.T (Remote Administration Tool), if you want to find out more about
it simply use Google.

My trojan allows me to access your accounts, your camera and microphone.
[cut, but you get the idea]</pre>
</samp>
<p>So <code>tropes@</code> gets routed to my inbox; in fact, anything @ my domain gets routed to the same inbox. This is what is meant by the term <em>wildcard</em> above: any value is a match. As well as allowing for spam provenance like the example above, this also helps with email filtering: if you're dealing with a certain company by email, your account email address can be <code>thatcompany@yourdoma.in</code> and your preferred email client can automatically filter any mail received to that address, into the appropriate place.</p>
<p>If you've purchased a domain, there are levels of email service available to you: one is fully-hosted service, where the Big Providers like Microsoft and Google offer the ability to use their servers for all email handling, so your domain essentially falls under their control for email purposes.</p>
<h2>Configuring Postfix</h2>
<p>At the other end of the spectrum is the self-hosted mailserver, where a machine under your control handles and stores email for the domain. For this quick note, we'll be installing and configuring the Postfix mail package on a Debian Linux machine. The <a href="https://wiki.debian.org/Postfix">Debian Wiki</a> has a useful guide on installation and post-install steps like configuring DKIM and greylists, but it boils down to <code>apt install postfix</code> for our purposes.</p>
<p>The above guide has a section on aliasing, where emails to one address get automatically forwarded to another. We'll be setting up a wildcard alias, which involves a couple of steps; first is to add an <code>aliases</code> file.</p>
<samp>
 <h3>Adding an aliases file</h3>
 <pre>echo "*: youracct" &gt;&gt; /etc/aliases
newaliases</pre>
 <h3>Configuring postfix to use the aliases</h3>
 <pre>postconf -e "alias_maps = hash:/etc/aliases"
postconf -e echo "alias_database = hash:/etc/aliases"</pre>
</samp>
<p>This enables postfix to treat any incoming address as though it were coming to a user of that name, but we'll also need to add a virtual alias for the domain routing:</p>
<samp>
 <h3>Adding a virtual alias map</h3>
 <pre>echo "yourdomai.in magic" &gt;&gt; /etc/postfix/virtual
echo "@yourdomai.in youracct" &gt;&gt; /etc/postfix/virtual
postmap /etc/postfix/virtual</pre>
 <h3>Configuring postfix with the virtual map</h3>
 <pre>postconf -e "virtual_alias_maps = hash:/etc/postfix/virtual"
service postfix reload</pre>
</samp>
<p>And in theory, we're done: email sent to any address at your domain should now land in your local mailbox. Delivery of the mail to your client of choice through IMAP is outside the scope of this quick hack, but I've used <code>dovecot</code> for a good while, and haven't had any issues.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">The Curious Case of Debian 12 and the SSH Failure</title>
 <link href="https://imrannazar.com/articles/linux-upgrade-fail" rel="alternate" type="text/html" title="The Curious Case of Debian 12 and the SSH Failure" />
 <id>https://imrannazar.com/articles/linux-upgrade-fail</id>
 <summary>A dive into the perils of running your own mailserver, when something terrible goes wrong with an upgrade.</summary>
 <category term="Articles" />
 <published>Tue, 02 Jan 2024 08:56:07 +0000</published>
 <content type="text/html"><![CDATA[
   <p>This site is served out of a DigitalOcean droplet that I've had since perhaps 2013, which was set up with Debian 7.0 Wheezy; the same machine is my mailserver. The system has been upgraded over the years, all the way up to Debian 11 (Bullseye), and has always been fun to try to keep up to date.</p>
<h2>It starts so innocently...</h2>
<p>It was just after Halloween 2023, and I was signing up to some SaaS provider's service. The site popped up a message saying I'd be receiving a verification email with a thing to click on, and then I could log in. Fairly normal signup behaviour for a site at this point.</p>
<p>Except the email never arrived. I headed over to <code>mail.log</code> to see what Postfix was saying...</p>
<samp>
 <h3>Excerpt from /var/log/mail.log</h3>
 <pre>postfix/smtpd[1141504]: connect from m206-43.eu.mailgun.net
postfix/smtpd[1141504]: SSL_accept error from m206-43.eu.mailgun.net: -1
postfix/smtpd[1141504]: warning: TLS library problem: error:14094412:SSL
   routines:ssl3_read_bytes:sslv3 alert bad certificate:../ssl/record/rec_layer_s3.c:1543:
   SSL alert number 42:
postfix/smtpd[1141504]: lost connection after STARTTLS from m206-43.eu.mailgun.net</pre>
</samp>
<p>Well, that's weird. A little searching around reveals a <a href="https://serverfault.com/questions/806141/is-the-alert-ssl3-read-bytessslv3-alert-bad-certificate-indicating-that-the-s">thread on StackExchange</a> where a helpful <code>dave_thompson_085</code> has this advice:</p>
<blockquote>
 <p>Receiving alert bad certificate (code 42) means the server demands you authenticate with a certificate, and you did not do so, and that caused the handshake failure...</p>
 <p>Find a certificate issued by a CA in the 'acceptable' list...</p>
</blockquote>
<p>So there's some kind of problem with the other end's CA. But it's Mailgun, you'd expect them to have a handle on keeping things up to date; let's check what their certificate looks like.</p>
<samp>
 <pre>$ openssl s_client -showcerts -connect api.mailgun.net:443
CONNECTED(00000005)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root G2
verify return:1
depth=1 C = US, O = DigiCert Inc, CN = DigiCert Global G2 TLS RSA SHA256 2020 CA1
verify return:1
depth=0 C = US, ST = Texas, L = San Antonio, O = "MAILGUN TECHNOLOGIES, INC", CN = *.api.mailgun.net
verify return:1
...</pre>
</samp>
<p>This isn't the certificate used by Mailgun when attempting to send that email, but it is <em>a</em> certificate used by Mailgun, and it's signed by the DigiCert CA. If we check with DigiCert, we see that the 2020 CA certificate <a href="https://knowledge.digicert.com/general-information/digicert-root-and-intermediate-ca-certificate-updates-2023">has been superceded as of March 2023</a>, so that's probably our problem: our copy of DigiCert's CA is too old.</p>
<p>No problem, we just update it:</p>
<samp>
 <pre># apt search ca-certificates
Sorting... Done
Full Text Search... Done
ca-certificates/stable,now 20210119 all [installed]
  Common CA certificates</pre>
</samp>
<p>Ah, right, yes. Bullseye has certificates up to 2021, and any CAs newer than that are in Debian 12 (Bookworm). And this, as I tooted at the time, is where things go awry:</p>
<figure>
 <iframe src="https://hachyderm.io/@Two9A/111381684178090138/embed" class="mastodon-embed" style="max-width: 95%; border: 0" width="600"></iframe>
 <script src="https://hachyderm.io/embed.js" async="async"></script>
 <figcaption>The state of affairs as of 5pm on Nov 9th</figcaption>
</figure>
<h2>And now we have a problem</h2>
<p>After the upgrade to Bookworm, connections over ssh would drop immediately:</p>
<samp>
 <pre>$ ssh imrannazar.com
Connection closed
$ ssh -v imrannazar.com
OpenSSH_8.1p1, LibreSSL 2.7.3
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 47: Applying options for *
...
debug1: SSH2_MSG_KEXINIT sent
Connection closed
$</pre>
</samp>
<p>So what's going on here? Evidently <em>something</em> about the server's new version of ssh has broken incoming connections... Let's get into the VM's console to start a debug copy of ssh on a different port, and see what happens.</p>
<samp>
 <h3>Running a debug sshd on the server</h3>
 <pre># /usr/sbin/sshd -D -d -o Port=9001
...
Missing privilege separation directory: /run/sshd
# mkdir /run/sshd
# /usr/sbin/sshd -D -d -o Port=9001</pre>
 <h3>Connecting to the debug sshd</h3>
 <pre>$ ssh -p9001 imrannazar.com
Connection closed
$</pre>
</samp>
<p>At least it's consistently crashing. Flipping back to the VM console, we get:</p>
<figure>
 <img src="/content/img/ssh-arc4random-console.png" alt="VM console with crashed sshd">
 <figcaption>VM console with output of sshd having crashed</figcaption>
</figure>
<p>Aha, a lead! This error looks suspiciously like it would cause things to fall over in a heap:</p>
<blockquote><code>Fatal glibc error: cannot get entropy for arc4random</code></blockquote>
<h2>arc4random and the getrandom syscall</h2>
<p>Why would this suddenly become a problem in Debian 12, when it wasn't a thing before? As it turns out, <code>arc4random</code> is a method of generating random numbers that's been in OpenBSD for years, but only made it to glibc (and thus to OpenSSH on Linux) <a href="https://www.phoronix.com/news/GNU-Glibc-arc4random-Functions">in July 2022</a>. My previous Bullseye kernel was up to date as of Jan 2021, so it makes sense that my previously installed OpenSSH didn't have the support required.</p>
<p>Now, what is the ssh daemon doing to get this error? A useful way of finding out which system calls are being made by a given program is to run it through <code>strace</code>:</p>
<samp>
 <pre># strace -f /usr/sbin/sshd -D -d -o Port=9001
...
[pid  1402] poll([{fd=7, events=POLLIN}, {fd=8, events=POLLIN}], 2, -1 &lt;unfinished ...&gt;
[pid  1640] &lt;... write resumed&gt;)        = 81
[pid  1640] getrandom(0x7f721688bd90, 16, 0) = -1 ENOSYS (Function not implemented)
[pid  1640] openat(AT_FDCWD, "/dev/urandom", O_RDONLY|O_NOCTTY|O_CLOEXEC) = -1 EMFILE (Too many open files)
[pid  1640] writev(2, [{iov_base="Fatal glibc error: cannot get en"..., iov_len=53}], 1) = -1 EFBIG (File too large)
[pid  1640] --- SIGXFSZ {si_signo=SIGXFSZ, si_code=SI_USER, si_pid=1640, si_uid=104} ---
[pid  1402] &lt;... poll resumed&gt;)         = 1 ([{fd=7, revents=POLLIN|POLLHUP}])
...</pre>
</samp>
<p>Here we see the ssh daemon start up as process 1402; a few hundred lines of strace's call log have been omitted here, as we're interested in what happens when it blocks waiting for connections. As we connect with an ssh client, the sshd wakes up process 1640 which was spawned as a handler.</p>
<p>The first thing the handler does is try to generate a random block of bytes to use for key exchange. According to the Phoronix page linked earlier:</p>
<blockquote>The implementation is based on scalar Chacha20 with per-thread cache. It uses getrandom or /dev/urandom as fallback to get the initial entropy...</blockquote>
<p>We see here that both the <code>getrandom</code> syscall and the <code>urandom</code> fallback failed. Without random data to start the key exchange, the handler crashes out. Now we know <em>why</em> we can't connect over ssh, what can we do?</p>
<h2>Kernel versions</h2>
<p>A good overview of the history of random number generators in Linux is <a href="https://lwn.net/Articles/884875/">this LWN article by Jake Edge</a>, which states that the <code>getrandom</code> syscall was added in Linux 3.17; when combined with this quote from the manual page for the corresponding C function, we're led to a particular conclusion:</p>
<blockquote>
 <h4>Errors</h4>
 <p><strong>ENOSYS</strong>: The glibc wrapper function for getrandom() determined that the underlying kernel does not implement this system call.</p>
</blockquote>
<p>So the kernel doesn't support <code>getrandom</code>. But I just upgraded to Bookworm, Debian 12, and I specifically saw <code>linux-image-6.1.0</code> get installed...</p>
<samp>
 <pre># uname -a
Linux 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2+deb7u2 x86_64 GNU/Linux</pre>
</samp>
<p>In what can only be seen as a testament to the stability of Linux's syscall API, I've been running the original Wheezy kernel from ten years ago, through all the upgrades. But I've rebooted more than once in the intervening time, so even though I haven't rebooted since the upgrade, I should be running the 5.10 kernel bundled in with Bullseye?</p>
<p>In a stroke of genius from the admins at DigitalOcean, it's possible to set your VM to use a bootloader which isn't the system's default <code>grub</code> installation. As it turns out, that's how my VM was set up:</p>
<figure>
 <img src="/content/img/ssh-arc4random-kernel.png" alt="DO admin panel showing Debian 7.0 as the boot kernel">
 <figcaption>DigitalOcean admin panel, showing 'Debian 7.0' as the boot kernel</figcaption>
</figure>
<p>Swap it over to the recommended GrubLoader, reboot, and ssh suddenly started working again.</p>
<h2>Another day set on fire</h2>
<p>And so we lose another day to the vagaries of amateur systems administration: after six hours, lots of cursing, and at least two instances of "wait, <em>what</em>" being uttered, I got my mailserver back to the state it was in that morning, and received that verification email I was waiting for.</p>
<p>Good thing Nov 9th wasn't a workday... Oh wait.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Nested Threads and the Mastodon Context API</title>
 <link href="https://imrannazar.com/articles/mastodon-nested-threads" rel="alternate" type="text/html" title="Nested Threads and the Mastodon Context API" />
 <id>https://imrannazar.com/articles/mastodon-nested-threads</id>
 <summary>Like many microblogging platforms, Mastodon displays posts and replies in a flat list; this can get confusing when conversations get deeply nested and branched. The Mastodon Context API offers a way to retrieve parent-child relationships between replies; this article looks at how those can be converted into a traversable tree.</summary>
 <category term="Articles" />
 <published>Sat, 02 Dec 2023 13:08:27 +0000</published>
 <content type="text/html"><![CDATA[
   <p>If you've ever been doomscrolling on a microblogging site like Mastodon (other brands are available), you'll have noticed that the conversations that result from a given message are presented as a flat list:</p>
<figure class="left-aligned">
 <ul>
  <li><em>The original message, by Alice</em></li>
  <li>Bob, in reply to Alice</li>
  <li>Alice, in reply to Bob</li>
  <li>Charlie, in reply to Bob</li>
  <li>Alice, in reply to Charlie</li>
  <li>Dave, in reply to Alice</li>
  <li>Eva, in reply to Alice</li>
  <li>Dave, in reply to Eva</li>
 </ul>
</figure>
<p>In this example, we can see some kind of conversation between Alice (the original poster) and Bob, with an interjection by Charlie; we also see two other comment threads. This is all derived from context, however, and there's no obvious structure to the threads. A nested presentation could perhaps be more conducive to understanding the flow of the conversation here:</p>
<figure class="left-aligned">
 <em>The original message, by Alice</em>
 <ul>
  <li>Bob
   <ul>
    <li>Alice</li>
    <li>Charlie
     <ul>
      <li>Alice</li>
     </ul>
    </li>
   </ul>
  </li>
  <li>Dave</li>
  <li>Eva
   <ul>
    <li>Dave</li>
   </ul>
  </li>
 </ul>
</figure>
<p>As it turns out, we can generate a tree-style view given the parent-child links from the first example; in this article I'll take a look at how one can use Mastodon's Context API to gather and produce the necessary data.</p>
<h2>Context: Ancestors and Descendants</h2>
<p>If one were to open a particular toot on the above-mentioned thread (say, Charlie's interjection), a Mastodon client would fetch the toot's context: its direct ancestors up the tree, as well as any descendent threads down the tree. Presentationally, this might be shown as:</p>
<figure class="left-aligned">
 <ul>
  <li><em>The original message, by Alice</em></li>
  <li>Bob, in reply to Alice</li>
  <li><strong>Charlie, in reply to Bob</strong></li>
  <li>Alice, in reply to Charlie</li>
 </ul>
</figure>
<p>We see the opened toot emphasised, with Alice's reply below; importantly, we only get Bob's reply to the OP because it's in the part of the tree that's a direct ancestor. If a Mastodon client were to present the full conversation, it would need to repeat this process with the top of the tree by fetching the context for Alice's message: every toot in the conversation would then be a member of the context's descendants.</p>
<p>In Mastodon's JSON API, this is implemented by the <code>context</code> endpoint, for which an example partial return looks like:</p>
<samp>
 <h3>Fetching context for a toot</h3>
 <pre>$ <kbd>curl</kbd> <var>https://mastodon.world/api/v1/statuses/111148878835275146/context</var> | <kbd>json_pp</kbd>
{
   <var>"ancestors"</var> : [
      {
         ...
         <var>"content"</var> : <var>"&lt;p&gt;This might have slipped under the radar these past few"</var>...,
         <var>"id"</var> : <var>"111148824053932160"</var>,
         <var>"in_reply_to_id"</var> : <kbd>null</kbd>,
         ...
      },
      {
         ...
         <var>"content"</var> : <var>"&lt;p&gt;&lt;span class=\"h-card\" translate=\"no\"&gt;&lt;a href=\"https://infose"</var>...,
         <var>"id"</var> : <var>"111148835195532183"</var>,
         <var>"in_reply_to_id"</var> : <var>"111148824053932160"</var>,
         ...
      }
   ],
   <var>"descendants"</var> : [
      {
         ...
         <var>"content"</var> : <var>"&lt;p&gt;&lt;span class=\"h-card\"&gt;&lt;a href=\"https://mastodon.or"</var>...,
         <var>"id"</var> : <var>"111149026486499760"</var>,
         <var>"in_reply_to_id"</var> : <var>"111148878835275146"</var>,
         ...
      }
   ]
}
 </pre>
</samp>
<p>Here we have a situation analogous to Charlie's conversation from earlier: the toot for which we requested context has a parent and grandparent, as well as a direct child. A few things should be noted:</p>
<dl>
 <dt>No "this" element</dt>
 <dd>The <code>context</code> endpoint returns ancestors and descendants of the given toot ID, but it doesn't return the content of that message; if we want the content of the toot in question, the separate <code>statuses</code> endpoint must be called.</dd>
 <dt>Parent-child relations</dt>
 <dd>Each ancestor and descendant returned follows a standard message format: along with the content (and other fields such as <code>account</code> describing the author), each message has an <code>id</code> and an <code>in_reply_to_id</code>. The latter indicates the parent message for which this is a child.</dd>
 <dt>Root node</dt>
 <dd>The top of the tree is the first ancestor in the list. We can see that it's the OP because the <code>in_reply_to_id</code> is <code>null</code>: it has no parent.</dd>
</dl>
<p>Having obtained the root node's ID from our <code>context</code> call, we can issue another <code>context</code> request to obtain parent-child links for the full conversation thread. This call will return no ancestors, and a batch of descendants:</p>
<samp>
 <h3>Fetching context for the root of the tree</h3>
 <pre>$ <kbd>curl</kbd> <var>https://mastodon.world/api/v1/statuses/111148824053932160/context</var> |
<kbd>jq</kbd> <var>'keys[] <kbd>as</kbd> $k | (.[$k] | (.[] | {id: <s>.id</s>, parent: <s>.in_reply_to_id</s>}))'</var>
{
  <kbd>"id"</kbd>: <var>"111148835195532183"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111148878835275146"</var>,
  <kbd>"parent"</kbd>: <var>"111148835195532183"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149026486499760"</var>,
  <kbd>"parent"</kbd>: <var>"111148878835275146"</var>
}
{
  <kbd>"id"</kbd>: <var>"111148886753997430"</var>,
  <kbd>"parent"</kbd>: <var>"111148835195532183"</var>
}
{
  <kbd>"id"</kbd>: <var>"111148912289735390"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149031550141696"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149299225622339"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149308672212244"</var>,
  <kbd>"parent"</kbd>: <var>"111149299225622339"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149319647286908"</var>,
  <kbd>"parent"</kbd>: <var>"111149308672212244"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149323173850002"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149387367883525"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}
{
  <kbd>"id"</kbd>: <var>"111149724821007295"</var>,
  <kbd>"parent"</kbd>: <var>"111148824053932160"</var>
}</pre>
</samp>
<h2>Converting parent-child links to a tree</h2>
<p>Once we have a list of parent-child relationships between nodes in the conversation, we can build a nested array of node IDs and their children: this will involve attaching a <code>children</code> array to each node of toot data, and filling the array with references to the direct children. In PHP, we could go about the production of the tree as follows:</p>
<samp>
 <h3>PHP code to generate a conversation tree given a root toot ID</h3>
 <pre>$mastodon_inst = <var>'mastodon.world'</var>;
$root_id = </var>'111148824053932160'</var>;

<s>// First, we fetch the root toot...</s>
$root = <kbd>json_decode</kbd>(<kbd>file_get_contents</kbd>(<kbd>sprintf</kbd>(
  <var>'%s/api/v1/statuses/%s'</var>,
  $mastodon_inst,
  $root_id
)), <kbd>true</kbd>);

<s>// Then context for the root</s>
$ctx = <kbd>json_decode</kbd>(<kbd>file_get_contents</kbd>(<kbd>sprintf</kbd>(
  <var>'%s/api/v1/statuses/%s/context'</var>,
  $mastodon_inst,
  $root_id
)), </var>true</var>);

<s>// Initialise a map of toots by ID</s>
$toots_by_id = [$root[<var>'id'</var>] =&gt; ($root + [<var>'children'</var> =&gt; []])];

<s>// There will only ever be descendants in the context</s>
<kbd>foreach</kbd> ($ctx[<var>'descendants'</var>] <kbd>as</kbd> &amp;$child) {
  $child[<var>'children</var>'] = [];
  $toots_by_id[$child[<var>'id'</var>]] = &amp;$child;
}

<s>// Finally, add each toot to the map as a child of its parent</s>
<kbd>foreach</kbd> ($toots_by_id <kbd>as</kbd> &amp;$subtoot) {
  <kbd>if</kbd> ($subtoot[<var>'in_reply_to_id'</var>]) {
    $toots_by_id[$subtoot[<var>'in_reply_to_id'</var>]][<var>'children'</var>][] = &amp;$subtoot;
  }
}</pre>
</samp>
<p>With the map filled in, a little light recursion is sufficient to generate a printed representation of the tree:</p>
<samp>
 <h3>Printing the tree structure</h3>
 <pre><kbd>function</kbd> print_toot($toot, $level = <var>0</var>) {
  <kbd>printf</kbd>(
    <var>"%s[%s] (%s)\n"</var>,
    str_repeat(<var>'  '</var>, $level),
    $toot[<var>'id'</var>],
    $toot[<var>'account'</var>][<var>'acct'</var>]
  );
  <kbd>foreach</kbd> ($toot[<var>'children'</var>] <kbd>as</kbd> $child) {
    print_toot($child, $level + <var>1</var>);
  }
}
print_toot($toots_by_id[$root_id]);</pre>
 <h3>Our sample tree, as printed by the above</h3>
 <pre>[111148824053932160] (briankrebs@infosec.exchange)
  [111148835195532183] (QuatermassTools@infosec.exchange)
    [111148878835275146] (penguin42@mastodon.org.uk)
      [111149026486499760] (mkoek@mastodon.nl)
    [111148886753997430] (ozdreaming@infosec.exchange)
  [111148912289735390] (ePD5qRxX@mastodon.online)
  [111149031550141696] (dwaites@infosec.exchange)
  [111149299225622339] (CyberLeech@cyberplace.social)
    [111149308672212244] (neurovagrant@masto.deoan.org)
      [111149319647286908] (CyberLeech@cyberplace.social)
  [111149323173850002] (VZ@fosstodon.org)
  [111149387367883525] (systemadminihater@cyberplace.social)
  [111149724821007295] (j@jaesharp.social)</pre>
</samp>
<h2>And we're done</h2>
<p>An implementation much like this has been used on <a href="https://threadtree.xyz/">ThreadTree</a>, the page I wrote when the original annoyance came up. The only additional note regarding the <a href="https://github.com/Two9A/ThreadTree">code behind ThreadTree</a> is that in my case, the annoyance started on Twitter, so the code still refers to tweets in many places even though the site functionality has been ported to Mastodon; the principle of nested threading and contexts applies in much the same fashion.</p>
<p>Thanks go to <a href="https://shkspr.mobi/blog/2022/11/getting-started-with-mastodons-conversations-api/">Terence Eden's article on this very topic</a> which helped with the building of ThreadTree, and <a href="https://hachyderm.io/@mapgiedev">mapgie</a> who (re-)introduced me to Twitter and caused this whole mess.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Seven Snippets of Modern CSS I Used To Rebuild My Site</title>
 <link href="https://imrannazar.com/articles/site-refresh-modern-css" rel="alternate" type="text/html" title="Seven Snippets of Modern CSS I Used To Rebuild My Site" />
 <id>https://imrannazar.com/articles/site-refresh-modern-css</id>
 <summary>A few months ago, I refreshed the design of my personal site; here&#039;s a list of a few bits of modern CSS that were used in the rebuild.</summary>
 <category term="Articles" />
 <published>Wed, 01 Nov 2023 08:19:48 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Back in the depths of time (we're talking perhaps 2008), I set up a site on the imrannazar.com domain with a set of articles lifted from an even older page, and some CSS based on what seemed like a good idea at the time. This is how that came out in the Way Back When:</p>
<figure>
 <img src="/content/img/new-blog-css-oldblog.webp" alt="2008-vintage screenshot of this place">
 <figcaption>
  Figure 1: Screenshot of this place before the redesign<br>
  (Courtesy of the <a href="https://archive.org">Wayback Machine</a>)
 </figcaption>
</figure>
<p>Fifteen years later, this build was starting to really show its age: built in an era before mobile viewports were common, it would always render as a desktop site, and it had various vestiges of Internet Explorer compatibility, such as this excellent hack that was common at the time to allow for transparent PNG support.</p>
<samp>
 <pre>#wrapper #foot {
  <kbd>filter</kbd>: progid:DXImageTransform.Microsoft.AlphaImageLoader(
    sizingMethod=<var>crop</var>,
    src=<var>'../img/foot.png'</var>
  );
}
#wrapper &gt; #foot {
  <kbd>background</kbd>: url(<var>../img/foot.png</var>) <kbd>no-repeat top left</kbd>;
}</pre>
</samp>
<p>When the idea of rebuilding this place came about towards the end of 2023, it seemed high time to make use of some of the more modern CSS features that have slowly crept into common usage and good browser support in the intervening span. Let's pick through the stylesheet and see which CSS techniques are being used that weren't at the time of the previous design.</p>
<h2>Variables</h2>
<p>At the top of the new stylesheet, we find:</p>
<samp>
 <pre>:root {
  --g-bg: <var>#e5dacc</var>;
  --g-text: <var>black</var>;
  --g-fig: <var>#d4c1aa</var>;
  ...
}
body {
  <kbd>background</kbd>: var(<var>--g-bg</var>);
  <kbd>color</kbd>: var(<var>--g-text</var>);
}</pre>
</samp>
<p>Defining these variables on the <code>:root</code> pseudo-class makes them available throughout the stylesheet, meaning we can define colours or other values in one place. This makes switching out and testing of colour themes and palettes much easier; I tried a few palettes before settling on the current values, which was made simple by not having to hunt for usages of the particular colour values to swap them out.</p>
<p>It also makes colour usage more semantic: the page background isn't an arbitrary hex string, it's <code>--g-bg</code> and that's much more readable when scanning through the rest of the styling. This means that such features as, for example, switching the site to dark mode are made possible simply by switching out the definitions in this block.</p>
<p><em>Now there's an idea... Let me get back to that another time.</em></p>
<h2>Webfonts</h2>
<p>Immediately below the variable definition, we find a couple of webfont definitions for the header (<a href="https://fonts.google.com/specimen/Over+the+Rainbow">Over the Rainbow</a>) and code blocks (<a href="https://levien.com/type/myfonts/inconsolata.html">Inconsolata</a>):</p>
<samp>
 <pre>@font-face {
  <kbd>font-family</kbd>: <var>'OverTheRainbow'</var>;
  <kbd>font-weight</kbd>: normal;
  <kbd>font-style</kbd>: normal;
  <kbd>src</kbd>: url(<var>/assets/overtherainbow.ttf</var>) format(<var>'truetype'</var>);
 }
 @font-face {
   <kbd>font-family</kbd>: <var>'Inconsolata'</var>;
   <kbd>font-weight</kbd>: normal;
   <kbd>font-style</kbd>: normal;
   <kbd>src</kbd>: url(<var>/assets/inconsolata.ttf</var>) format(<var>'truetype'</var>);
 }</pre>
</samp>
<p>With these fonts defined, their names can be used in any following rule. For example, code blocks have this styling:</p>
<samp>
 <pre>main samp pre {
  <kbd>font</kbd>: <var>16pt Inconsolata</var>, monospace;
  <kbd>background</kbd>: var(<var>--g-fig</var>);
}</pre>
</samp>
<p>Webfont definitions support multiple file formats; for simplicity and highest compatibility, I've used the TTF files here.</p>
<p>Now, webfonts had been a thing for some time when the previous site design was put together, but the main thing preventing their use in the design at the time was...</p>
<h2>transform: rotate</h2>
<p>A stylistic choice for the page header was to rotate the text slightly, but back in '08 this wasn't possible in a well-supported way. Modern browser support for the <code>transform</code> rule is fairly complete, so this is finally useful. The syntax of the rule itself is fairly simple:</p>
<samp>
 <pre>h1 {
  ...
  <kbd>text-align</kbd>: <var>center</var>;
  <kbd>transform</kbd>: rotate(<var>-3deg</var>);
}</pre>
</samp>
<p>This also means I don't have to implement the headers of each page as a transparent PNG laid over the header graphic, which significantly reduces page weight and helps not only with load speed, but with accessibility: having the page's main header be an image can be confusing when passed through a screenreader or other accessibility tools, but as text the header's existence is made clear.</p>
<h2>font-display: fallback</h2>
<p>The main disadvantage of webfonts is that they need to be loaded in by the browser, and that can only occur after the CSS has been downloaded:</p>
<figure class="left-aligned">
 <ul>
  <li>Browser loads the page HTML</li>
  <li>Page HTML contains a <code>&lt;link&gt;</code> to the stylesheet</li>
  <li>Browser downloads the CSS</li>
  <li>Stylesheet contains a <code>@font-face</code> rule defining a webfont</li>
  <li>Browser downloads the webfont file(s)</li>
 </ul>
</figure>
<p>For the period between the CSS being available, and the webfonts loading in, the default behaviour is to blank out the element being rendered for lack of a font to use. You can, however, specify a fallback behaviour which is to use the second font defined against the element (and if that's also a webfont, fall back further until the browser reaches a standard font that's on the machine).</p>
<p>Having these elements visible (in the wrong font) before their fonts load in may seem weird from a design perspective, but it's good for accessibility and page responsiveness: if you can see all the text on the page immediately, a screenreader (or a search engine's bot, for that matter) can too, and it won't have to wait for everything to load.</p>
<p>Fallback behaviour can be configured on the <code>@font-face</code>:</p>
<samp>
 <pre>@font-face {
  <kbd>font-family</kbd>: <var>'OverTheRainbow'</var>;
  <kbd>font-weight</kbd>: normal;
  <kbd>font-style</kbd>: normal;
  <kbd>src</kbd>: url(<var>/assets/overtherainbow.ttf</var>) format(<var>'truetype'</var>);
  <kbd>font-display</kbd>: fallback;
}
h1 {
  ...
  <kbd>font-family</kbd>: <var>OverTheRainbow</var>, sans-serif;
}</pre>
</samp>
<p>There's one more piece of the puzzle regarding the behaviour of the page heading on this site, and it's how the header responds to resizing and different sizes of viewport. For that, we come to perhaps the best new addition to CSS of all:</p>
<h2>font-size: clamp</h2>
<p>With <code>clamp</code>, one is able to specify a flexible measurement with a range above/below which the measurement won't go. For example, the <code>h1</code> on this page is defined in full as below:</p>
<samp>
 <pre>h1 {
  <kbd>font</kbd>: clamp(<var>24px</var>, <var>3.5vw</var>, <var>60px</var>)/<var>1.4</var> <var>OverTheRainbow</var>, sans-serif;
}</pre>
</samp>
<p>Let's break this down:</p>
<ul>
 <li>The font family is our <code>OverTheRainbow</code> webfont, with a fallback to the browser's built-in sans-serif;</li>
 <li>The spacing between lines is 1.4, leaving a gap between lines of 40% of a line;</li>
 <li>The size (the height of a line) is 3.5% of the viewport width, meaning wider windows get a larger font, but;</li>
 <li>The font size won't grow past 60px on extremely wide browsers, and won't shrink below 24px as the browser gets narrower. It's <em>clamped</em> between these two constraints.</li>
</ul>
<p>And if you're thinking these figures look a little arbitrary, that's because they are: some experimentation was needed to arrive at values which work sensibly with the design.</p>
<p>Clamping the font size handles responsiveness of the heading text, but the other component that resizes is the scrap-of-paper design, which is an element background. For this, we need...</p>
<h2>background-size: contain and aspect-ratio</h2>
<p>In the way back when, you could define image backgrounds on elements in CSS, but your options were to have them repeat horizontally/vertically or ...not. Modern CSS gives you two new tools as options to <code>background-size</code>: there's <code>cover</code>, which tries to completely cover the element by sizing up the background and cropping the edges, and there's <code>contain</code> which tries to fit the image into the element in full, perhaps leaving uncovered gaps in either the vertical or the horizontal.</p>
<p>For our use-case, we need <code>contain</code> because we want the whole image visible:</p>
<samp>
 <pre>header {
  <kbd>background</kbd>: url(<var>/assets/headback.webp</var>) no-repeat top left;
  <kbd>background-size</kbd>: contain;

  <kbd>width</kbd>: <var>100%</var>;
  <kbd>min-width</kbd>: <var>900px</var>;
  <kbd>max-width</kbd>: <var>1450px</var>;

  <kbd>aspect-ratio</kbd>: <var>145</var>/<var>35</var>;
  <kbd>max-height</kbd>: <var>350px</var>;
}</pre>
</samp>
<p>With this set of rules, we're giving the browser significant contraints in how it's to render the header: full-width, but within a particular range, and always maintaining a 145/35 aspect ratio. In addition, when the browser comes to fill in the background, <code>contain</code> means it will lean towards keeping the full image visible rather than trying to crop any edges.</p>
<h2>Things not covered here</h2>
<p>We've made it as far as defining the header, and already modern CSS has come in very useful for creating a design that was simply not possible in the dark days of the late oughts. As we come down the page, there are more CSS features in use that we won't cover in detail here:</p>
<ul>
 <li><strong>Flexbox</strong>: Figures are defined as columnar flex containers, meaning multiple images or tables can be held in a figure and the browser will work out how to position them to maintain the column.</li>
 <li><strong>Grid</strong>: The lists of links in the footer are held in a grid, which simulates the old-world table layout in a semantically sensible fashion; in particular, the third column is specified to be wider than the others, and the browser works out the actual widths without us having to do the menial calculation.</li>
 <li><strong>Media queries</strong>: Responsiveness is all about being able to handle different sizes of viewport, and below 900px the desktop variant of the site begins to fall apart. With media queries, we can define a new variant that applies down to 600px, and yet another variant that works on mobile devices below that size; with the smallest variant in particular, we can even replace the header element and use a new mobile-specific background and aspect ratio.</li>
</ul>
<p>And there are features coming to wider support in CSS that haven't yet been employed here, the most compelling of which is rule nesting. To take a sample from further down the stylesheet:</p>
<samp>
 <pre>main samp {
  <kbd>font</kbd>: <var>16pt Inconsolata</var>, monospace;
  <kbd>background</kbd>: var(<var>--g-fig</var>);
  <kbd>display</kbd>: block;
}
main samp pre { <kbd>margin</kbd>: <var>0</var>; <kbd>padding</kbd>: <var>1em</var>; <kbd>overflow</kbd>: auto; }
main samp kbd { <kbd>color</kbd>: var(<var>--g-code-keyword</var>); }
main samp var { <kbd>color</kbd>: var(<var>--g-code-var</var>); }
main samp s { <kbd>color</kbd>: var(<var>--g-code-comment</var>); <kbd>text-decoration</kbd>: none; }</pre>
</samp>
<p>There's a bunch of redundancy in the match specifications here, and one of the more compelling reasons to use CSS pre-processors like Sass has, in the past, been that one can nest rules like this to make for cleaner code to work with:</p>
<samp>
 <pre>main samp {
  <kbd>font</kbd>: <var>16pt Inconsolata</var>, monospace;
  <kbd>background</kbd>: var(<var>--g-fig</var>);
  <kbd>display</kbd>: block;
  
  pre { <kbd>margin</kbd>: <var>0</var>; <kbd>padding</kbd>: <var>1em</var>; <kbd>overflow</kbd>: auto; }
  kbd { <kbd>color</kbd>: var(<var>--g-code-keyword</var>); }
  var { <kbd>color</kbd>: var(<var>--g-code-var</var>); }
  s { <kbd>color</kbd>: var(<var>--g-code-comment</var>); <kbd>text-decoration</kbd>: none; }
}</pre>
</samp>
<p>A pre-processor means a build step, which means a build process, and suddenly your plain HTML/CSS site has become a Whole Thing. With CSS nesting coming to browsers, this will soon be natively supported client-side, and will no longer be a reason to have a build process at all.</p>
<p>Overall, I'm happy with how the refresh has come out; here's to another fifteen years. Let's see how CSS advances in the interim, and what's possible (and widely supported) the next time I get bored and decide to rebuild this place.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Binary Golfing in Commodore BASIC</title>
 <link href="https://imrannazar.com/articles/binary-golf-in-c64-basic" rel="alternate" type="text/html" title="Binary Golfing in Commodore BASIC" />
 <id>https://imrannazar.com/articles/binary-golf-in-c64-basic</id>
 <summary>This year&#039;s Binary Golf Grand Prix recently closed for submissions, and I only just found about it. This article covers a couple of approaches for this particular code golf problem on the Commodore 64.</summary>
 <category term="Articles" />
 <published>Sun, 01 Oct 2023 08:25:31 +0000</published>
 <content type="text/html"><![CDATA[
   <p>When I say I partake in the occasional bit of golf, I don't mean the sport involving balls and clubs. I've never tried that, but I have gone in for code golf in the past; the object of code golf is similar in that you're aiming for a low number. For code golf, the aim is to achieve the required functionality or implement the algorithm with the smallest code.</p>
<p>Explorations of the smallest possible thing in a particular area aren't unprecedented here: the first article on this site is <a href="/articles/the-smallest-nds-rom"><em>The Smallest Nintendo DS ROM</em></a>, from 2006. So when I heard about the <a href="https://binary.golf/">Binary Golf Grand Prix</a> I was left with no choice but to put in an attempt. Unfortunately, I learned of the existence of BGGP #4 around two hours before it closed for submissions, so I ended up handing in a scrap of PHP. But let's look at what could've been...</p>
<h2>The Task at Hand</h2>
<p>This year's problem is specified as follows:</p>
<blockquote>
 <p><strong>Create the smallest self-replicating file.</strong></p>
 <p>A valid submission will:
  <ul>
   <li>Produce exactly 1 copy of itself</li>
   <li>Name the copy "4"</li>
   <li>Not execute the copied file</li>
   <li>Print, return, or display the number 4</li>
  </ul>
 </p>
</blockquote>
<p>The most natural thought that arises, unbidden, is how one would go about this on the Commodore 64. Commodore BASIC has the built-in <code>SAVE</code> command, so our submission might be as simple as:</p>
<samp>
 <h3>C64 BASIC program that saves itself to disk</h3>
 <pre>10 <kbd>SAVE</kbd> <var>"4"</var>, <var>8</var>
20 <kbd>PRINT</kbd> <var>4</var></pre>
</samp>
<p>As the task here is to generate the <em>smallest</em> file, we should look at how this program is stored in memory (and thus, on disk). Commodore BASIC stores programs almost entirely as written, and the code execution process includes a parsing step which tokenises the program before it's executed. So the above program looks like this if we use <a href="https://vice-emu.sourceforge.io">VICE</a>'s memory monitor:</p>
<samp>
 <h3>The above BASIC program, in memory</h3>
 <pre>(C:$e5cf) <kbd>m</kbd> <var>0800</var>
&gt;C:0800  00 <var>0e 08</var> <kbd>0a  00</kbd> <s>94 20 22  34 22 2c 20  38 00</s> <var>16 08</var>   ...... "4", 8...
&gt;C:0810  <kbd>14 00</kbd> <s>99 20  34 00</s> 00 00  00 00 ff ff  ff ff 00 00   ... 4.....????..</pre>
</samp>
<h2>BASIC program storage and tokenisation</h2>
<p>We can see the program starts at address <code>$0801</code> hexadecimal: this is the case for every BASIC program on the C64, whether typed in or loaded. Each line starts with a pointer to the next line, allowing the BASIC interpreter to rapidly work through the program if it needs to determine the program length or find a particular line to change its content.</p>
<p>After the pointer to the next line comes the line number: two bytes, in little-endian format (small byte first), which is standard for the 6502-derived processor inside the C64. So we see the first line is numbered <code>$000a</code>, 10. And after this comes the line content itself: <code>94 20 22 34 22 2c 20 38 00</code>.</p>
<p>As a program is typed into the BASIC interpreter, it's tokenised: any keywords in the line get replaced by token values before being stored in memory. We can see in this line that <code>SAVE</code> has been replaced by command token <code>$94</code>, such that if this value comes at the start of a command the interpreter knows this is a <code>SAVE</code> command without needing to read and parse the individual letters of the word "SAVE".</p>
<p>The rest of the command is not tokenised, and responsibility for parsing this arguments string is passed to whichever routine in the BASIC interpreter is handling the command. In this case, the rest of the command is ASCII text: <code>&lt;space&gt;"4",&lt;space&gt;8</code>; note that the spaces are preserved as they were entered in the program. The arguments are terminated by a zero byte.</p>
<p>The second line is similarly structured: a <code>$99</code> token representing the <code>PRINT</code> command, and an arguments string of <code>20 34</code>, representing <code>&lt;space&gt;4</code>.</p>
<h2>Golfing in C64 BASIC</h2>
<p>Now we've seen how the BASIC program is stored internally, we have direction for a round of golf. The first step is to remove the spaces:</p>
<samp>
 <h3>Golf, first hole: Removing spaces</h3>
 <pre>10<kbd>SAVE</kbd><var>"4",8</var>
20<kbd>PRINT</kbd>4</pre>
</samp>
<p>One might be tempted to remove the quotes around the filename, relying on whatever type coercion may exist in the BASIC interpreter to convert <code>4</code> into a string. Unfortunately, this isn't a thing on the C64:</p>
<samp>
 <h3>Golf, bogey on the second hole</h3>
 <pre>10<kbd>SAVE</kbd><var>4,8</var>
20<kbd>PRINT</kbd><var>4</var>
<kbd>RUN</kbd>

?TYPE MISMATCH  ERROR IN 10</pre>
</samp>
<p>Commodore BASIC does, however, support multiple commands on one line, with the colon separator. Thus, we can combine the two commands of our program and remove the four bytes associated with the second line pointer and line number:</p>
<samp>
 <h3>Golf, third hole: Combining lines</h3>
 <pre>10<kbd>SAVE</kbd><var>"4",8</var>:<kbd>PRINT</kbd><var>4</var></pre>
</samp>
<p>This program is stored in memory as below:</p>
<samp>
 <h3>Fully golfed out BASIC program</h3>
 <pre>(C: $e5cf) <kbd>m</kbd> <var>0800</var>
&gt;C:0800  00 <var>0f 08</var> <kbd>0a  00</kbd> <s>94 22 34  22 2c 38</s> 3a  <s>99 34 00</s> 00   ......"4",8:.4..</pre>
</samp>
<p>We see that the two commands have been stored as one line, so there's one next-line pointer (which refers to the byte after the end of the program); it also becomes plain that a zero byte isn't the only thing that can end an arguments string in C64 BASIC. The colon, byte <code>$3a</code>, can also act as an end-of-arguments delimiter, denoting the end of a command and the start of another.</p>
<p>Our final result in Commodore BASIC is 14 bytes. Is it possible to produce a smaller program by switching to machine language, and communicating with the disk drive through Commodore DOS directly?</p>
<h2>Saving files in Commodore DOS</h2>
<p>One advantage of using such a venerable computer as the C64 for this task is that the documentation is extensive and copious. There are eleven separate commentaries on the <code>SAVE</code> routine available in the <a href="https://www.pagetable.com/c64ref/kernal/#SAVE">C64 Kernal API</a> reference, including detailed explanation of the internal workings; for our purposes, we'll use the example routine provided by Commodore's own Programmer's Reference, which gives a sequence of operations for using <code>SAVE</code>:
<blockquote>
 <ol>
  <li>Use the SETLFS routine and the SETNAM routine (unless a SAVE with no file name is desired on "a save to the tape recorder"),</li>
  <li>Load two consecutive locations on page 0 with a pointer to the start of your save (in standard 6502 low byte first, high byte next format).</li>
  <li>Load the accumulator with the single byte page zero offset to the pointer.</li>
  <li>Load the X and Y registers with the low byte and high byte re- spectively of the location of the end of the save.</li>
  <li>Call this routine.</li>
 </ol>
</blockquote>
<p>In this case, we'll be saving to disk (device 8), so we'll want to call both <code>SETLFS</code> and <code>SETNAM</code> before running through the save. There are two things we'll need to note for the save itself:</p>
<dl>
 <dt>Load location</dt>
 <dd>
  <p>As mentioned above, when a BASIC program is loaded from disk, it always loads to the same location (the start of BASIC memory, <code>$0801</code> hexadecimal); a machine-language program doesn't have this restriction, and can be loaded into memory anywhere. To facilitate this, the first two bytes of the program as stored on disk are actually the address to which it should be loaded. Accordingly, when saving the program this must be accounted for by setting up the load address in memory beforehand (in little-endian format, as the Programmer's Reference mentions above).</p>
  <p>We also have the extra stipulation that this program needs to be self-replicating: if the file saved by this code is reloaded, it will need to behave the same way. To that end, the load address for the program will need to be written by the program itself, to a location just before the program, and the concatenated block saved together.</p>
 </dd>
 <dt>Program size</dt>
 <dd><p>BASIC keeps track of how long the entered program is, so it can determine how much memory needs to be saved to disk; our machine-language program will have to set up the amount of data to save without this help being available.</p></dd>
</dl>
<p>At this point, it's already becoming obvious that our machine-language attempt will be longer than 14 bytes to perform the same task as the BASIC program above, but to quote from a certain classic game show:</p>
<blockquote>I've started, so I'll finish...</blockquote>
<samp>
 <h3>C64 machine language program that saves itself to disk</h3>
 <pre>
FILENAME = <var>$002A</var>        <s>; An unused byte in zero page</s>
PROGPTR = <var>$009B</var>         <s>; An unused block of two bytes</s>
PROGSTART = <var>$C0C0</var>       <s>; Program runs from here</s>
MEMSTART = <var>$C0BE</var>        <s>; SAVE starts from here</s>

    <kbd>processor</kbd> <var>6502</var>
    <kbd>org</kbd> PROGSTART

start:
    <kbd>lda</kbd> <var>#1</var>              <s>; Logical file 1</s>
    <kbd>ldx</kbd> <var>#8</var>              <s>; Disk drive 0 (device 8)</s>
    <kbd>ldy</kbd> <var>#255</var>            <s>; No secondary command</s>
    <kbd>jsr</kbd> <var>$FFBA</var>           <s>; SETLFS</s>

    <kbd>lda</kbd> <var>#'4</var>             <s>; Our filename: "4"</s>
    <kbd>sta</kbd> FILENAME        <s>; Store the name</s>
    <kbd>lda</kbd> <var>#1</var>              <s>; It's one byte long</s>
    <kbd>ldx</kbd> #&lt;FILENAME      <s>; And it's stored in zero page</s>
    <kbd>ldy</kbd> #&gt;FILENAME      <s>; at this address</s>
    <kbd>jsr</kbd> <var>$FFBD</var>           <s>; SETNAM</s>

    <kbd>lda</kbd> <var>#$c0</var>            <s>; Our load location ($C0C0)</s>
    <kbd>sta</kbd> MEMSTART        <s>; Written to the two bytes</s>
    <kbd>sta</kbd> MEMSTART + <var>1</var>    <s>; before the program in memory</s>

    <kbd>lda</kbd> #&lt;MEMSTART      <s>; Set up our indirect pointer</s>
    <kbd>sta</kbd> PROGPTR         <s>; from the start of the file</s>
    <kbd>lda</kbd> #&gt;MEMSTART      <s>; to our two-byte pointer store</s>
    <kbd>sta</kbd> PROGPTR + <var>1</var>     <s>; in zero page</s>

    <kbd>lda</kbd> #&lt;PROGPTR       <s>; Pointer to the start of file</s>
    <kbd>ldx</kbd> #&lt;end           <s>; Actual location of the end of file</s>
    <kbd>ldy</kbd> #&gt;end           <s>; (including the two-byte header)</s>
    <kbd>jsr</kbd> <var>$FFD8</var>           <s>; SAVE</s>

    <kbd>lda</kbd> <var>#4</var>              <s>; We need to print or return 4</s>
    <kbd>rts</kbd>                 <s>; So let's return 4</s>
end:</pre>
</samp>
<h2>Conclusion and caveats</h2>
<p>The above machine-language program clocks in at 50 bytes, almost four times as large as the equivalent BASIC routine. There's some scope for reducing that number, but we don't have a hope of reaching the 14 bytes that a higher-level representation affords us. It should also be noted that we're not attempting to <em>print</em> the number 4 as per the task description, as this would require another call out to the <abbr title="Yes, I know it's a kernel">Kernal</abbr> and/or recycling of BASIC routines to do the same.</p>
<p>There is a level below this, of course, which we haven't reached today: direct communication with the disk drive to push the program to disk, bypassing Commodore DOS (at least at the computer end). The Kernal API is an abstraction on top of this, meaning we don't have to worry about the disk drive's serial bus and other vagaries of the implementation.</p>
<p>This little game of code golf has allowed us a look into why higher-level languages exist at all: not only do they allow us to perform tasks such as "save a file to disk" with less code, they also abstract away complications such as setting the filename before writing a file. Perhaps BASIC shouldn't be maligned quite so much.</p>
<p>Thanks go to the <a href="https://www.masswerk.at/6502/disassembler.html">Online 6502 Disassembler</a> by Norbert Landsteiner, and the <a href="https://github.com/dasm-assembler/dasm/">dASM assembler</a> whose name always makes me think it's a disassembler.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Preprocessor Definitions in WebAssembly</title>
 <link href="https://imrannazar.com/articles/wasm-preprocessor-defines" rel="alternate" type="text/html" title="Preprocessor Definitions in WebAssembly" />
 <id>https://imrannazar.com/articles/wasm-preprocessor-defines</id>
 <summary>When hand-writing WebAssembly it can get problematic to refer to particular constants by their value instead of being able to put a name to them. I put together a simple preprocessor to allow for constants to be handled by name, and in this article I look at how the preprocessor works with the WebAssembly Text format.</summary>
 <category term="Articles" />
 <published>Tue, 05 Sep 2023 14:37:04 +0000</published>
 <content type="text/html"><![CDATA[
   <p>So I've slowly been working on converting the emulation core behind <a href="http://c64clicker.com/">Commodore Clicker</a> to hand-written WebAssembly, to see if it helps with performance at all. Writing WASM by hand is something that's been covered excellently by others (I first picked up the concepts from <a href="https://blog.scottlogic.com/2018/04/26/webassembly-by-hand.html">Colin at Scott Logic</a>), but one thing that's been a bugbear recently is an inability to name constants.</p>
<h2>The Problem</h2>
<p>The Commodore 64 has, as the name implies, 64kB of static RAM that can be written to at any time; however, its processor only has access to a 64kB address space, and somehow needs to fit the BASIC and <abbr title="Yes I know it's spelled 'Kernel'">Kernal</abbr> DOS ROMs, as well as peripheral access, into that same space. Commodore achieved this by overloading the processor's onboard I/O port so you can "switch in" the ROMs and peripheral space, and switch them out if you need access to all the RAM.</p>
<figure class="invertable">
 <img src="/content/img/wasm-define-mmap.png" alt="Commodore 64 memory map">
 <figcaption>Figure 1: Commodore 64 memory map</figcaption>
</figure>
<p>For example, the Kernal ROM maps into memory at <code>$E000</code>, but only if it's been enabled at the CPU port level by switching on bit 1 (<code>HIRAM</code>). In the emulator's memory controller, this particular mapping might read as follows in JavaScript.</p>
<samp>
 <h3>MMU.js: Kernal area mapping</h3>
 <pre><kbd>const</kbd> CPUPORT = <var>0x0001</var>;
<kbd>const</kbd> HIRAM = <var>2</var>;

<kbd>export const</kbd> readByte = (addr) =&gt; {
    <kbd>switch</kbd> (addr &amp; <var>0xF000</var>) {
        <s>// RAM, BASIC, peripheral areas</s>
        ...
        <s>// Kernal ROM</s>
        <kbd>case</kbd> <var>0xE000</var>:
        <kbd>case</kbd> <var>0xF000</var>:
            <kbd>if</kbd> (memory[CPUPORT] &amp; HIRAM) {
                <kbd>return</kbd> ROM.kernal[addr &amp; <var>0x1FFF</var>];
            } <kbd>else</kbd> {
                <kbd>return</kbd> memory[addr];
            }
            <kbd>break</kbd>;
    }
};</pre>
</samp>
<p>If we're to translate this to <abbr title="WebAssembly Text">WAT</abbr>, we'll first convert the <code>switch</code> statement to a function table:</p>
<samp>
 <h3>MMU.wat: Indirect call table</h3>
 <pre>(<kbd>memory</kbd> (<kbd>import</kbd> <var>"mem"</var>) <var>2</var>)
(<kbd>table</kbd> <var>16</var> <kbd>anyfunc</kbd>)
(<kbd>elem</kbd> (i32.<kbd>const</kbd> <var>0</var>)
    <s>;; RAM, BASIC, peripheral areas
    ;; ...</s>
    $read_kernal
    $read_kernal
)

(<kbd>type</kbd> $readfunc (<kbd>func</kbd> (<kbd>param</kbd> i32) (<kbd>result</kbd> i32)))
(<kbd>func</kbd> $read (<kbd>param</kbd> $addr i32) (<kbd>result</kbd> i32)
    <s>;; table[(addr &amp; 0xF000) &gt;&gt; 12]()</s>
    (<kbd>call_indirect</kbd> (<kbd>type</kbd> $readfunc)
        (<kbd>get_local</kbd> $addr)
        (i32.<kbd>shr_u</kbd>
            (i32.<kbd>and</kbd> (<kbd>get_local</kbd> $addr) (i32.<kbd>const</kbd> <var>0xF000</var>))
            (i32.<kbd>const</kbd> <var>12</var>)
        )
    )
)</pre>
</samp>
<p>Now, this isn't terrible so far. We have two contiguous 64k-value blocks of memory (one for RAM, one for the mapped ROMs), and there are some magic constants in the <code>$read</code> main handler, but they make sense in the context of needing to extract four bits from the address and using those to index the function table. Where the constants start to make less sense is in <code>$read_kernal</code>:</p>
<samp>
 <h3>MMU.wat: Read from Kernal if it's mapped in</h3>
 <pre>(<kbd>func</kbd> $read_kernal (<kbd>param</kbd> $addr i32) (<kbd>result</kbd> i32)
    (i32.<kbd>load8_u</kbd>
        (<kbd>if</kbd> (<kbd>result</kbd> i32)
            (i32.<kbd>and</kbd> (i32.<kbd>load</kbd> (i32.<kbd>const</kbd> <var>0x0001</var>)) (i32.<kbd>const</kbd> <var>2</var>))
            (<kbd>then</kbd>
                (i32.<kbd>add</kbd>
                    (i32.<kbd>and</kbd> (<kbd>get_local</kbd> $addr) (i32.<kbd>const</kbd> <var>0xFFFF</var>))
                    (i32.<kbd>const</kbd> </var>0x10000</var>)
                )
            )
            (<kbd>else</kbd>
                (i32.<kbd>and</kbd> (<kbd>get_local</kbd> $addr) (i32.<kbd>const</kbd> <var>0xFFFF</var>))
            )
        )
    )
)</pre>
</samp>
<p>This is more inscrutable, especially if (as was the case for me) this code has been written and then left to marinate for a year before coming back to attempt to read it again. It would be much more readable if the above function could instead use defined constants:</p>
<samp>
 <h3>MMU.wat: Read from Kernal, but with constants</h3>
 <pre>
(define <s>CPUPORT</s> (i32.<kbd>const</kbd> <var>0x0001</var>))
(define <s>HIRAM</s> (i32.<kbd>const</kbd> <var>2</var>))
(define <s>ROM_MEMORY_START</s> (i32.<kbd<const</kbd> <var>0x10000</var>))

(<kbd>func</kbd> $read_kernal (<kbd>param</kbd> $addr i32) (<kbd>result</kbd> i32)
    (i32.<kbd>load8_u</kbd>
        (<kbd>if</kbd> (<kbd>result</kbd> i32)
            (i32.<kbd>and</kbd> (i32.<kbd>load</kbd> <s>CPUPORT</s>) <s>HIRAM</s>)
            (<kbd>then</kbd>
                (i32.<kbd>add</kbd>
                    (i32.<kbd>and</kbd> (<kbd>get_local</kbd> $addr) (i32.<kbd>const</kbd> <var>0xFFFF</var>))
                    <s>ROM_MEMORY_START</s>
                )
            )
            (<kbd>else</kbd>
                (i32.<kbd>and</kbd> (<kbd>get_local</kbd> $addr) (i32.<kbd>const</kbd> <var>0xFFFF</var>))
            )
        )
    )
)</pre>
</samp>
<h2>Handling S-expressions</h2>
<p>The above code makes use of a <code>define</code> keyword that doesn't exist in WASM, so we need something akin to the C preprocessor to parse through the WAT file picking up definitions and replacing their occurrences. Fortunately, WAT was designed to be a format that's quick and easy to handle programmatically (while still being at least halfway usable by human standards): a WebAssembly Text file is one big Lisp-style S-expression, and each element within the file is itself a nested S-expression.</p>
<p>This means we can use S-expression handling libraries to quickly move from the WAT file to an internal representation that can be worked with. One such library is <a href="https://github.com/jd-boyd/sexpdata">sexpdata by Joshua Boyd</a>, which is an S-expression parser and dumper for Python. If we point our fledgling MMU file at <code>sexpdata.load</code>, something usable starts to fall out:</p>
<samp>
 <h3>mwat.py: Loading the WAT file</h3>
 <pre><kbd>import</kbd> sys
<kbd>from</kbd> sexpdata <kbd>import</kbd> load

<kbd>def</kbd> main():
    filename = sys.argv[<var>1</var>]
    <kbd>print</kbd>(load(<kbd>open</kbd>(filename)))

<kbd>if</kbd> __name__ == <var>"__main__"</var>:
    main()</pre>
 <h3>Initial debug output</h3>
 <pre>[Symbol('module'), [Symbol('define'), Symbol('CPUPORT'), [Symbol('i32.const'), Symbol('0x0001')]], [Symbol('define'), ...</pre>
</samp>
<p>Arrays with <code>Symbol</code> objects (which are an internal construct to <code>sexpdata</code>) and other arrays inside. We can work with this by using a recursive function to handle the array representing the whole file: if an array is found inside, it will need to be processed recursively, unless it's an array that holds a <code>define</code> statement.</p>
<p>Definitions can be made at any level of the WAT file, so any extracted definitions will need to be passed down to deeper levels of recursion, and merged with any definitions that are passed in from higher levels. So that means the list of definitions will need to be a parameter to the preprocessor:</p>
<samp>
 <h3>mwat.py: Preprocessor function call</h3>
 <pre><kbd>import</kbd> sys
<kbd>from</kbd> sexpdata <kbd>import</kbd> load, dumps

<kbd>def</kbd> process(sexp, defines):
    new_defines = {}
    <s># First pass: Find immediate descendent s-exp's which define macros</s>
    <s># TODO</s>

    <s># Macros defined at this level override any of the same name higher up</s>
    <s># NOTE: We don't want to mutate the parent's dict, we want our own copy</s>
    merged_defines = defines.copy() | new_defines

    <s># Second pass: Replace at this level, recurse if deeper levels encountered</s>
    <s># TODO</s>
    <kbd>return</kbd> [i <kbd>for</kbd> i <kbd>in</kbd> sexp]

<kbd>def</kbd> main():
    filename = sys.argv[<var>1</var>]
    <s># Top-level process, with no existing definitions in the dict</s>
    <kbd>print</kbd>(dumps(process(load(<kbd>open</kbd>(filename)), {})))

<kbd>if</kbd> __name__ == <var>"__main__"</var>:
    main()</pre>
</samp>
<h2>Detecting and replacing definitions</h2>
<p>We come to the crux of the problem: filling in the TODOs above. In the first pass, this is fairly simple: we'd like to find any arrays where the first element is a <code>Symbol('define')</code>, and pull out the associated definition. Let's take the first line of debug output again.</p>
<samp>
 <h3>Initial debug output</h3>
 <pre>[Symbol('module'),
 [Symbol('define'), Symbol('CPUPORT'), [Symbol('i32.const'), Symbol('0x0001')]],
 [Symbol('define'), Symbol('HIRAM'), [Symbol('i32.const'), 2]], ...</pre>
</samp>
<p>We see that some elements in the file have been parsed as scalar values, and some as Symbol's. As Python doesn't have a native <code>is-array</code>, we can't directly find arrays in order to perform the first-element check mentioned above; we can, however, use numpy's <code>isscalar</code> to detect scalar values, and <code>isinstance</code> for Symbol's. From here, it's fairly simple to detect and extract definition clauses.</p>
<samp>
 <h3>Extracting definitions</h3>
 <pre><kbd>from</kbd> numpy <kbd>import</kbd> isscalar
<kbd>from</kbd> sexpdata <kbd>import</kbd> Symbol

<kbd>def</kbd> is_scalar_or_symbol(i):
    <kbd>return</kbd> isscalar(i) <kbd>or</kbd> <kbd>isinstance</kbd>(i, Symbol)

<kbd>def</kbd> process(sexp, defines):
    new_defines = {}
    <kbd>for</kbd> i <kbd>in</kbd> sexp:
        <kbd>if not</kbd> is_scalar_or_symbol(i):
            <kbd>if</kbd> i[<var>0</var>] == Symbol(<var>'define'</var>):
                new_defines[i[<var>1</var>]] = i[<var>2</var>]
    ...</pre>
</samp>
<p>And once we have the definitions to be used on this level, replacement is fairly simple. There are four types of item that will need action:</p>
<ul>
 <li><strong>Arrays where the first element is <code>Symbol('define')</code></strong>: Exclude;</li>
 <li><strong>Arrays where the first element is not <code>Symbol('define')</code></strong>: Recurse;</li>
 <li><strong>Scalars or plain Symbol's which are defined</strong>: Replace;</li>
 <li><strong>Scalars or plain Symbol's which aren't defined</strong>: Copy.</li>
</ul>
<samp>
 <h3>List comprehension for replacing definitions</h3>
 <pre><kbd>return</kbd> [
    merged_defines[i] <kbd>if</kbd> (
        is_scalar_or_symbol(i) <kbd>and</kbd> merged_defines.get(i)
    )                                   <s># Replace</s>
    <kbd>else</kbd> i <kbd>if</kbd> is_scalar_or_symbol(i)    <s># Copy</s>
    <kbd>else</kbd> process(i, merged_defines)     <s># Recurse</s>
    <kbd>for</kbd> i <kbd>in</kbd> sexp
    <kbd>if</kbd> is_scalar_or_symbol(i) <kbd>or</kbd> i[<var>0</var>] != Symbol(<var>'define'</var>)   <s># Exclude</s>
 ]</pre>
</samp>
<p>Putting everything together, the following GitHub Gist contains the final preprocessor script, as well as a sample input WAT file and the generated output:</p>
<p><a href="https://gist.github.com/Two9A/427985064d360342caaf4f7d5769aeef">https://gist.github.com/Two9A/427985064d360342caaf4f7d5769aeef</a></p>
<h2>Caveats and improvements</h2>
<p>The astute observer will already have noticed that circular definitions are not handled at all well by this script: if one <code>define</code> contains a keyword that's handled by another <code>define</code>, the final output is dependent on the order of definition. In addition, this replicates the behaviour of C's <code>#define</code> but it doesn't help with any of the other C-style preprocessor directives, notably <code>#include</code>; support for these is a matter for future expansion.</p>
<address>Imran Nazar, Sep 2023</address>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Ticketed</title>
 <link href="https://imrannazar.com/scifi/ticketed" rel="alternate" type="text/html" title="Sci-fi Shorts: Ticketed" />
 <id>https://imrannazar.com/scifi/ticketed</id>
 <summary>A long-awaited sequel to Prime Point, in which our brave protagonist finally jumps into a hyperspace-capable ship and ends up... somewhere.</summary>
 <category term="Original Writings" />
 <published>Wed, 15 Mar 2017 00:00:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>Originally released on <a href="https://www.deviantart.com/inazar/art/Ticketed-669188795">DeviantArt</a></em></p>
<hr>
<p>The initial probe had been dubbed Hyper One, the first successful test of a hyperspace tunneling engine: launched on a Paludis III twelve years ago, it had made its ponderous way to the Lagrange point sixty degrees ahead of the Earth in its orbit, taking a few months to get to its testing position. When the drive was spun up, it flicked across to somewhere in the vicinity of L4, sixty degrees behind Earth, in half a second. The tunneling engine was a miracle of high-speed space travel, but Hyper One and two subsequent probes had only carried bacterial or other small samples.
<p>Hyper Four would be the first test of a hyperspace tunneling engine with humans on board. The engine had been retrofitted to one of SpaceX's old service capsules: with their Mars cycler fully up and running as of a few years ago, their stocks of Dragon capsules were simply taking up space and any use for them was encouraged. Life support and environmental controls were still working perfectly in this particular capsule: in its previous job as fifth (and seventh) crew service mission to the Space Station, it had encountered no issues except for a harder-than-usual ocean landing on the second use. That made it a fairly cheap capsule for the Hyper team to pick up.
<p>James Kent, veteran of the Hyper series, had been voluntold as the crew member for this fourth mission: Dragon had made its way out under its own steam, and was now parked in orbit around the Earth-Moon system's L2 point: that helped to simplify the calculations by removing nearby gravitational influences, while still being visible from Earth so the Hyper team could track Four from the ground.
<p>James thought back to the first test of Hyper One, and the astonishment they'd all felt when One had jumped more than 0.2 AU in the blink of an eye. And now he'd be doing the same, looking out the portholes of a capsule at the space below (or was it above?) realspace. To say he was excited was probably understating it.
<p>The radio crackled into life.
<p>"Hyper Four, this is Houston again. Our board is green for spin-up; we're sending you updated hyper-coordinates for the tunneling engine. Please confirm."
<p>"Programmed in," James stated. "Let's do this, over."
<p>"Copy, Hyper Four. Engage when ready."
<p>James flipped a switch over his head, and the carrier signal from Earth immediately redshifted into oblivion. Light flooded in through the capsule's portholes.
<p>Nothing else seemed to happen for a few seconds. Time passed on board Hyper Four, the clock by James's hand ticked by at its normal rate, but the light from outside remained unchanging and constant. Then the radio cracked into life again.
<blockquote>License and registration, please.</blockquote>
<p>"Er, Houston... do you read?"
<p>James didn't see how he could be receiving radio from above (or was it below) the skein of realspace, since the light waves wouldn't make it outside the constraints of untunneled space...
<blockquote>Come on, you can't pop up in the middle of the B6631 and cause disruption to traffic, then plead ignorance. You've been pulled over to the shoulder; your license, please.</blockquote>
<p>"Alright, if this is Guinea base, Funny Joke, guys. I'll have to ask you how you're tunneling radio into the hyperskein when I get back; over."
<blockquote>We're talking at cross-purposes here. Do you have a license, sir?</blockquote>
<p>"I guess I'll play along. No, I guess?"
<blockquote>Oh, you're one of those. Right, well, you may regard your patch of space as sovereign, but if you make use of the federal galactic highways, you'll need to abide by federal law. As you don't have your license, I'm issuing you a summons to Sirius district court: you'll need to appear in-</blockquote>
<p>"Wait, wait, hold on. What do you mean, federal highways? We only just connected to hyperspace, I didn't know that-"
<blockquote>Oh, you're one of <i>those</i>. Right, well. Er, let's see... Firstly, it's infraspace, the interbrane region below realspace, that you're in.</blockquote>
<p>"Clears that one up, I guess..."
<blockquote>Secondly, your tunnel intersected the B6631 galactic highway and has left a hole in lane four. And not a smooth hole, either; your engine is terribly noisy in its hookup to the interbrane.</blockquote>
<p>"Er, right. I wasn't aware that the B6631 ...ran through here. It's not like we have a map..."
<blockquote>Right, yeah, first-contacters, sure. I could've sworn there was a protocol for this... In light of your status, I've rescinded the summons to Sirius-f. Let me go talk to someone, I'll be back.</blockquote>
<p>James was left alone for a few minutes. Or at least, a few minutes passed on board the capsule; who knows what was happening in realspace. This... highways officer? that James had talked with, showed up on the radio again.
<blockquote>Alright, you're free to go. As I mentioned, you've been pulled over to the shoulder of the B6631, and my superiors have authorized me to write a map of the highway network to your support equipment's silicate substrate. Your nearest on-ramp is the core of the planet you refer to as Jupiter; please try not to drill any more holes in our roads.</blockquote>
<p>"Well, thank you. This is... amazing. I just have a couple of questi-"
<blockquote>"How do you speak my language" comes up surprisingly often with first-contacters, my superiors mentioned. Consider that your vehicle is built in realspace, and you're in the interbrane at the present time: all atomic connections are visible to those who can travel directly in the interbrane.</blockquote>
<p>"Right, yes... I guess my only other question is, how do we get to the core of Jupiter to join the highway?"
<blockquote>Surface roads aren't our concern, sir. Your local onramp was constructed some time ago.</blockquote>
<p>"Ok, well, er. Thank you..."
<blockquote>One more thing before I eject you into realspace, sir. I've also written our current emissions regulations into your vehicle's silicate; a vehicle with such noisy tunneling output as yours runs the risk of being impounded, and that's a court appearance that can't be rescinded. Have a good journey.</blockquote>
<p>And the light pouring into the capsule flicked off. The capsule's console screen started spewing text:
<pre>Determining position
12 degrees above the orbital plane; reorienting comms
Carrier signal obtained
Time elapsed since signal loss: 0.48 seconds</pre>
<p>"Er, Houston, Hyper Four. Boy, do I have a tale for you."
 ]]></content>
</entry>
<entry>
 <title type="html">That Time My Encrypted RAID Failed</title>
 <link href="https://imrannazar.com/shorts/that-time-my-encrypted-raid-failed" rel="alternate" type="text/html" title="That Time My Encrypted RAID Failed" />
 <id>https://imrannazar.com/shorts/that-time-my-encrypted-raid-failed</id>
 <summary>A short postmortem of the time my LUKS volume failed, what I did wrong at the time, and how I got the data back.</summary>
 <category term="Quick Hacks" />
 <published>Wed, 27 May 2015 00:00:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>It was early December, 2012. The world was all a-flutter about the impending reset of the Mayan calendar, but I was unconcerned, streaming music from my 8TB RAID5. Then the music stopped, at 30 seconds or so. I tried a few more files: some worked but only for a short while, some didn&#39;t load at all. This was an md RAID5 set of four 2TB disks, with a LUKS encrypted volume inside. Somehow, the area of disk 1 holding the critical &quot;key material&quot; had been corrupted, so the encryption key was in memory but not on the disk when I rebooted. I made three mistakes around that time:</p>
<ul>
<li>No backups. The traditional mistake.</li>
<li>Specifically, I didn&#39;t have the encryption master key written down, or any backups of the key material. (For future reference, you can get the master key for a running volume with <code>dmsetup table --showkeys</code>, and the LUKS header with key material from <code>cryptsetup luksHeaderBackup</code>.)</li>
<li>I set to the array in a panic, frantically swapping disks and overwriting md superblocks in an attempt to get a working configuration, all from the initrd&#39;s shell. This meant that, when I finally gave up, the disks were in an unknown order.</li>
</ul>
<p>Any sane person would write the data off as lost, but I decided to hold out a sliver of hope that it was only one disk that had gone bad, and that I&#39;d just failed to arrange things properly. I didn&#39;t want to futz with the disks any further, so any more work on them would have to wait until a disk large enough to hold all the images was available.</p>
<p>Fast forward to May 2015, and the release of that crazy SMR 8TB from Seagate. I ran out and pre-ordered one, seeing my chance, then set to <code>dd</code>&#39;ing the RAID5 member partitions over to the 8TB disk. (Yes, I should&#39;ve used ddrescue, but I got lucky, and the disks were physically fine.) Then I wrote <a href="https://gist.github.com/Two9A/f266b75513e3b2564e46">a script and some permutations</a> to run over the images of disks 1, 2 and 3 (in the order I&#39;d left them in) trying four different RAID5 layouts, four different chunk sizes and 24 permutations. It should be noted that I deliberately assembled the RAID from 3 out of 4 disks, to prevent a rebuild overwriting anything.</p>
<p>That script ran on disk combinations 1/2/3, 1/3/4 and 2/3/4, and generated 384 LUKS header backups. Then I ran <code>cryptsetup luksAddKey</code> against each of those backups, using a file containing 24 possible variations on the passphrase I&#39;d used to set up the encryption. So that&#39;s 9,216 attempts, most of which came back with &quot;No key available with this passphrase&quot;. But one attempt out of all of those looked different:</p>
<blockquote>
<p>luks.g413.ls.512: No key available with this passphrase.<br>luks.g413.ls.64: No key available with this passphrase.<br>luks.g431.la.128: No key available with this passphrase.<br>luks.g431.la.256: No key available with this passphrase.<br>luks.g431.la.512: No key available with this passphrase.<br>luks.g431.la.64: No key available with this passphrase.<br>luks.g431.ls.128: No key available with this passphrase.<br>luks.g431.ls.256: No key available with this passphrase.<br>luks.g431.ls.512: No key available with this passphrase.<br>luks.g431.ls.64:<br>Trying passphrase: In a hole in the ground, there lived a hobbit!<br>luks.1g23.ra.128: No key available with this passphrase.<br>luks.1g23.ra.256: No key available with this passphrase.<br>luks.1g23.ra.512: No key available with this passphrase.<br>luks.1g23.ra.64: No key available with this passphrase.  </p>
</blockquote>
<p>The degraded RAID set that <em>didn&#39;t</em> contain disk 2 was the right set. It turns out that the order I left the disks in all those years ago was 2/4/3/1, and the layout and chunk size were the defaults. Amazingly, the only thing that had been corrupted was the LUKS header on disk &quot;2&quot;, and all the encrypted blocks were fine.</p>
<p>Earlier today, I bought a second 8TB disk to copy all the data off; the first 8TB will be repurposed as its mirror. Ten minutes ago, I finished the song that was so rudely aborted by the Mayan apocalypse.</p>
<p>Lesson learned: if you&#39;re going to encrypt your disks, keep a backup of the master key somewhere. </p>
 ]]></content>
</entry>
<entry>
 <title type="html">RFC 7168: Hypertext Coffeepot Control Protocol for Tea Efflux Appliances</title>
 <link href="https://imrannazar.com/articles/rfc7168" rel="alternate" type="text/html" title="RFC 7168: Hypertext Coffeepot Control Protocol for Tea Efflux Appliances" />
 <id>https://imrannazar.com/articles/rfc7168</id>
 <summary>An update to HTCPCP (RFC 2324) to allow for the connection of networked tea-brewing devices. Published under the RFC Informational series.</summary>
 <category term="Articles" />
 <published>Tue, 01 Apr 2014 09:15:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>This document was published by the <a href="http://www.rfc-editor.org/">RFC Editor</a> on Apr 1, 2014.</em></p>
<p><em>Independent Submission<br>
Request for Comments: <a href="http://www.rfc-editor.org/rfc/rfc7168.txt">7168</a><br>
Updates: <a href="http://www.rfc-editor.org/rfc/rfc2324.txt">2324</a><br>
Category: Informational<br>
ISSN: 2070-1721</em></p>

<h2>Abstract</h2>

   <p>The Hyper Text Coffee Pot Control Protocol (HTCPCP) specification
   does not allow for the brewing of tea, in all its variety and
   complexity.  This paper outlines an extension to HTCPCP to allow for
   pots to provide networked tea-brewing facilities.</p>

<h2>Status of This Memo</h2>

   <p>This document is not an Internet Standards Track specification; it is
   published for informational purposes.</p>

   <p>This is a contribution to the RFC Series, independently of any other
   RFC stream.  The RFC Editor has chosen to publish this document at
   its discretion and makes no statement about its value for
   implementation or deployment.  Documents approved for publication by
   the RFC Editor are not a candidate for any level of Internet
   Standard; see Section 2 of RFC <a href="http://www.rfc-editor.org/rfc/rfc5741.txt">5741</a>.</p>

   <p>Information about the current status of this document, any errata,
   and how to provide feedback on it may be obtained at
   <a href="http://www.rfc-editor.org/info/rfc7168">http://www.rfc-editor.org/info/rfc7168</a>.</p>

<h2>Copyright Notice</h2>

   <p>Copyright (c) 2014 IETF Trust and the persons identified as the
   document authors.  All rights reserved.</p>

   <p>This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (<a href="http://trustee.ietf.org/license-info">http://trustee.ietf.org/license-info</a>) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.</p>

<h2>1.  Introduction</h2>

   <p>As noted in the <a href="http://www.rfc-editor.org/rfc/rfc2324.txt">Hyper Text Coffee Pot Control Protocol</a>,
   coffee is renowned worldwide as an artfully brewed caffeinated
   beverage, but coffee shares this quality with many other varied
   preparations based on the filtration of plant material.  Foremost,
   among these are the category of brews based on the straining of water
   through prepared leaves from a tea tree: the lineage and history of
   the tea genus will not be recounted as part of this paper, but
   evidence shows that the production of tea existed many thousands of
   years ago.</p>

   <p>The deficiency of HTCPCP in addressing the networked production of
   such a venerable beverage as tea is noteworthy: indeed, the only
   provision given for networked teapots is that they not respond to
   requests for the production of coffee, which, while eminently
   reasonable, does not allow for communication with the teapot for its
   intended purpose.</p>

   <p>This paper specifies an extension to HTCPCP to allow communication
   with networked tea production devices and teapots.  The additions to
   the protocol specified herein permit the requests and responses
   necessary to control all devices capable of making, arguably, the
   most popular caffeinated hot beverage.</p>

<h3>1.1.  Terminology</h3>

   <p>The key words <em>MUST</em>, <em>MUST NOT</em>, <em>REQUIRED</em>, <em>SHALL</em>, <em>SHALL NOT</em>,
   <em>SHOULD</em>, <em>SHOULD NOT</em>, <em>RECOMMENDED</em>, <em>MAY</em>, and <em>OPTIONAL</em> in this
   document are to be interpreted as described in RFC <a href="http://www.rfc-editor.org/rfc/rfc2119.txt">2119</a>.</p>

<h2>2.  HTCPCP-TEA Protocol Additions</h2>

   <p>The TEA extension to HTCPCP adapts the operation of certain HTCPCP
   methods.</p>

<h3>2.1.  <code>BREW</code> and <code>POST</code> Methods</h3>

   <p>Control of a TEA-capable pot is performed, as described in the base
   HTCPCP specification, through the sending of <code>BREW</code> requests.  <code>POST</code>
   requests are treated equivalently, but they remain deprecated.  Tea
   production differs from coffee, however, in that a choice of teas is
   often provided for client selection before the tea is brewed.  To
   this end, a TEA-capable pot that receives a <code>BREW</code> message of content
   type <code>message/teapot</code> <em>MUST</em> respond in accordance with the URI
   requested, as below.</p>

<h4>2.1.1.  The <code>/</code> URI</h4>

   <p>For the URI <code>/</code>, brewing will not commence.  Instead, an <code>Alternates</code>
   header as defined in RFC <a href="http://www.rfc-editor.org/rfc/rfc2295.txt">2295</a> <em>MUST</em> be sent, with the
   available tea bags and/or leaf varieties as entries.  An example of
   such a response is as follows:</p>

   <div class="sample">
    <div class="inner">
      Alternates: {"/darjeeling" {type message/teapot}},
                  {"/earl-grey" {type message/teapot}},
                  {"/peppermint" {type message/teapot}}
    </div>
   </div>

   <p>The following example demonstrates the possibility of
   interoperability of a TEA-capable pot that also complies with the
   base HTCPCP specification:</p>

   <div class="sample">
    <div class="inner">
      Alternates: {"/" {type message/coffeepot}},
                  {"/pot-0/darjeeling" {type message/teapot}},
                  {"/pot-0/earl-grey" {type message/teapot}},
                  {"/pot-1/peppermint" {type message/teapot}}
    </div>
   </div>

   <p>TEA-capable HTCPCP clients <em>MUST</em> check the contents of the <code>Alternates</code>
   header returned by a <code>BREW</code> request, and provide a specific URI for
   subsequent requests of the <code>message/teapot</code> type.</p>

   <p>A request to the <code>/</code> URI with a <code>Content-Type</code> header of
   <code>message/coffeepot</code> <em>SHOULD</em> also be responded to with an <code>Alternates</code>
   header in the above format, to allow TEA-capable clients the
   opportunity to present the selection of teas to the user if inferior
   caffeinated beverages have initially been requested.</p>

<h4>2.1.2.  Variety-Specific URIs</h4>

   <p>TEA-capable pots follow the base HTCPCP specification when presented
   with a <code>BREW</code> request for a specific variety of tea.  Pots <em>SHOULD</em>
   follow the recommendations for brewing strength given by each
   variety, and stop brewing when this strength is reached; it is
   suggested that the strength be measured by detection of the opacity
   of the beverage currently under brew by the pot.</p>

   <p>TEA-capable clients <em>SHOULD</em> indicate the end of brewing by sending a
   <code>BREW</code> request with an entity body containing <code>stop</code>; the pot <em>MAY</em>
   continue brewing beyond the recommended strength until this is
   received.  If the <code>stop</code> request is not sent by the client, this may
   result in a state inversion in the proportion of tea to water in the
   brewing pot, which may be reported by some pots as a negative
   strength.</p>

   <p>If a <code>BREW</code> command with an entity body containing <code>stop</code> is received
   before the recommended strength is achieved, the pot <em>MUST</em> abort
   brewing and serve the resultant beverage at lesser strength.  Finding
   the preferred strength of beverage when using this override is a
   function of the time between the TEA-capable pot receiving a <code>start</code>
   request and the subsequent <code>stop</code>.  Clients <em>SHOULD</em> be prepared to
   make multiple attempts to reach the preferred strength.</p>

<h3>2.2.  Modified Header Fields</h3>

   <p>HTCPCP-TEA modifies the definition of one header field from the base
   HTCPCP specification.</p>

<h4>2.2.1.  The <code>Accept-Additions</code> Header Field</h4>

   <p>It has been observed that some users of blended teas have an
   occasional preference for teas brewed as an emulsion of cane sugar
   with hints of water.  To allow for this circumstance, the <code>Accept-Additions</code>
   header field defined in the base HTCPCP specification is
   updated to allow the following options:

   <div class="sample">
    <div class="inner">
      addition-type   = ( "*"
                        | milk-type
                        | syrup-type
                        | sweetener-type
                        | spice-type
                        | alcohol-type
                        | sugar-type
                        ) *( ";" parameter )
      sugar-type      = ( "Sugar" | "Xylitol" | "Stevia" )
    </div>
   </div>

   <p>Implementers should be aware that excessive use of the <code>Sugar</code> addition
   may cause the <code>BREW</code> request to exceed the segment size allowed by the
   transport layer, causing fragmentation and a delay in brewing.</p>

<h3>2.3.  Response Codes</h3>

   <p>HTCPCP-TEA makes use of normal HTTP error codes and those defined in
   the base HTCPCP specification.</p>

<h4>2.3.1.  300 Multiple Options</h4>

   <p>A <code>BREW</code> request to the <code>/</code> URI, as defined in Section 2.1.1, will
   return an <code>Alternates</code> header indicating the URIs of the available
   varieties of tea to brew.  It is <em>RECOMMENDED</em> that this response be
   served with a status code of 300, to indicate that brewing has not
   commenced and further options must be chosen by the client.</p>

<h4>2.3.2.  403 Forbidden</h4>

   <p>Services that implement the <code>Accept-Additions</code> header field <em>MAY</em> return
   a 403 status code for a <code>BREW</code> request of a given variety of tea, if
   the service deems the combination of additions requested to be
   contrary to the sensibilities of a consensus of drinkers regarding
   the variety in question.</p>

   <p>A method of garnering and collating consensus indicators of the most
   viable combinations of additions for each variety to be served is
   outside the scope of this document.</p>

<h4>2.3.3.  418 I'm a Teapot</h4>

   <p>TEA-capable pots that are not provisioned to brew coffee may return
   either a status code of 503, indicating temporary unavailability of
   coffee, or a code of 418 as defined in the base HTCPCP specification
   to denote a more permanent indication that the pot is a teapot.</p>

<h2>3.  The <code>message/teapot</code> Media Type</h2>

   <p>To distinguish messages destined for TEA-capable HTCPCP services from
   pots compliant with the base HTCPCP specification, a new MIME media
   type is defined by this document.  The <code>Content-Type</code> header of a <code>POST</code>
   or <code>BREW</code> request sent to a TEA-capable pot <em>MUST</em> be <code>message/teapot</code> if
   tea is to be requested.</p>

<h2>4.  Environmental Considerations</h2>

   <p>As noted in Section 2.1, a <code>BREW</code> request with a <code>Content-Type</code> header
   field of <code>message/teapot</code> to a TEA-capable pot will result in an
   <code>Alternates</code> header being sent with the response, and a pot will not be
   brewed.  However, if the <code>BREW</code> request has a <code>Content-Type</code> of
   <code>message/coffeepot</code>, and the pot is capable of brewing coffee, the
   service's behavior will fall back to the base HTCPCP specification
   and a pot will be brewed.</p>

   <p>If the entity returned by the server when brewing commences contains
   a TEA-compliant <code>Alternates</code> header indicating <code>message/coffeepot</code> and
   the client does not want coffee, the client <em>SHOULD</em> then send a <code>BREW</code>
   request with an entity body containing <code>stop</code>.  This will result in
   wasted coffee; whether this is regarded as a bad thing is user-
   defined.</p>

   <p>Such waste can be prevented by TEA-capable clients, by first
   requesting a <code>BREW</code> of type <code>message/teapot</code> and then allowing
   selection of an available beverage.</p>

<h2>5.  Security Considerations</h2>

   <p>As with the base HTCPCP specification, most TEA-capable pots are
   expected to heat water through the use of electric elements, and as
   such will not be in proximity to fire.  Therefore, no firewalls are
   necessary for communication with these pots to proceed.</p>

   <p>This extension does support communication with fired pots, however,
   which may require heat retention and control policies.  Care should
   be taken so that coal-fired pots and electrically heated kettles are
   not connected to the same network, to prevent pots from referring to
   any kettles on the network as darkened or otherwise smoke driven.</p>

<h2>6.  Acknowledgements</h2>

   <p>This extension to the HTCPCP specification would not be possible
   without the base specification, and research on networked beverage
   production leading up thereto.  In that vein, the author wishes to
   acknowledge the sterling work of <a href="http://larry.masinter.net/">Larry Masinter</a> in the development of
   the leading protocol for coffee pot communication.</p>

   <p>Many thanks also to <a href="http://phpro.org">Kevin Waterson</a> and <a href="http://pete-davis.info">Pete Davis</a>, for providing
   guidance and suggestions during the drafting of this document.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Let&#039;s Build a JPEG Decoder: Frames and Bitstreams</title>
 <link href="https://imrannazar.com/series/lets-build-a-jpeg-decoder/bitstreams" rel="alternate" type="text/html" title="Let&#039;s Build a JPEG Decoder: Frames and Bitstreams" />
 <id>https://imrannazar.com/series/lets-build-a-jpeg-decoder/bitstreams</id>
 <summary>Continuing a series exploring the concepts behind JPEG image compression, this part begins delving into the relationship between the image, its colour constituents and the encoded data by breaking open the Start of Frame segment.</summary>
 <category term="Series" />
 <published>Sun, 05 May 2013 22:18:50 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This article is part four of a series exploring the concepts and implementation of JPEG decoding; four parts are currently available, and others are expected to follow.</em>
 <ul>
  <li><a href="/series/lets-build-a-jpeg-decoder/concepts">Part 1: Concepts</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/structure">Part 2: File Structure</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/huffman-tables">Part 3: Huffman Tables</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/bitstreams">Part 4: Frames and Bitstreams</a></li>
 </ul>
</p>
<p><em>Download the code: <a href="http://imrannazar.com/content/files/jpegparse.zip">http://imrannazar.com/content/files/jpegparse.zip</a></em></p>
<p>Previously, I discussed the Huffman compression algorithm as implemented by JPEG, and a mechanism by which JPEG encoders pick the substitution values used for the compression. The image itself, in a baseline entropy-coded JPEG file, is stored in one "scan" as a stream of Huffman codes; the codes are of a variable length, and are not necessarily at even byte boundaries.</p>
<p>For this reason, it's a requirement that some kind of queue be introduced between the bytes of the file, and the values as seen by the JPEG decoder: this allows bits to be pushed onto the queue from the bytes of the file, and pulled out in varying amounts by the decoder. A single routine can thus be made the central routing point for any requests for variable-width symbols.</p>
<p>A queue of things, when used in this fashion, generally has two modes of operation: either there are enough things in the queue for the request to deal with, or additional reading has to be done before there are enough things in the queue to handle the request. In the case of a bit-level queue for reading from a file, as we need here, the number of bits requested is the determining factor. In the first example below, a queue holding five bits is asked to return the first three, and is able to handle the request without a problem.</p>
<figure class="img">
 <img src="/content/img/jpeg-bits-queue-full.png" alt="Request handling with a full queue">
 <figcaption>Figure 1: Request handling with sufficient content in the queue</figcaption>
</figure>
<p>If a request for four bits then comes in, the queue doesn't contain enough bits to handle the request, and must first fetch another full byte from the JPEG file (shown here in red).</p>
<figure>
 <img src="/content/img/jpeg-bits-queue-empty.png" alt="Request handling with an empty queue">
 <figcaption>Figure 2: Request handling when the queue is empty</figcaption>
</figure>
<h2>Implementing the bit queue</h2>
<p>A complication arises when trying to code an implementation of the bit queue as shown above: the output end of the queue is at the left, and if one contiguous value is used to store the queue, the left is the most-significant end with the highest-value bits. If we demarcate the queue as being 32 positions long, and define one 32-bit value as holding its entire contents, the above scenarios break down as follows:</p>
<dl>
 <dt>Pulling three bits</dt>
 <dd><ul>
  <li>The request is shorter than the queue length of 5, no reading from file happens.</li>
  <li>The output value is the top three bits of the queue, shifted down (32 - 3) bits to become the bottom three bits of an output value;</li>
  <li>The queue is shifted left three bits, and left with length of 2.</li>
 </ul></dd>
 <dt>Pulling another four bits</dt>
 <dd><ul>
  <li>The request is longer than the queue length of 2: a byte is read in, and shifted up (24 - 2) bits to join the queue;</li>
  <li>The queue is now 10 bits long, no more bytes need reading;</li>
  <li>The output value is the top four bits of the queue, shifted down (32 - 4);</li>
  <li>The queue is shifted left four bits, and left with length of 6.</li>
 </ul></dd>
</dl>
<p>At all times during the queue's operation, the next available bits are at the high-value end of the contiguous queue variable. An implementation of this may look like the following.</p>
<samp>
 <h3>jpeg.h: Definition of bit-resolution file reader</h3>
 <pre><kbd>class</kbd> JPEG {
    <kbd>private</kbd>:
        <s>// Read a number of bits from file</s>
        u16 readBits(<kbd>int</kbd>);
};</pre>
 <h3>jpeg.cpp: Bit-resolution file reader</h3>
 <pre>u16 JPEG::readBits(<kbd>int</kbd> len)
{
    <s>// The number of bits left in the queue, and the value represented</s>
    <kbd>static int</kbd> queueLen = <var>0</var>;
    <kbd>static</kbd> u32 queueVal = <var>0</var>;

    u8 readByte;
    u16 output;

    <kbd>if</kbd> (len &gt; queueLen) {
        <kbd>do</kbd> {
            <s>// Read a byte in, shift it up to join the queue</s>
            readByte = <kbd>fgetc</kbd>(fp);
            queueVal = queueVal | (readByte &lt;&lt; (<var>24</var> - queueLen));
            queueLen += <var>8</var>;
        } <kbd>while</kbd> (len &gt; queueLen);
    }

    <s>// Shift the requested number of bytes down to the other end</s>
    output = ((queueVal &gt;&gt; (<var>32</var> - len)) &amp; ((<var>1</var> &lt;&lt; len) - <var>1</var>));

    queueLen -= len;
    queueVal &lt;&lt;= len;

    <kbd>return</kbd> output;
}</pre>
</samp>
<h2>The JPEG SOF segment</h2>
<p>As mentioned in the previous part of this series, a JPEG file can define up to 32 Huffman code tables, each in their own <code>DHT</code> segment. A JPEG file holds the data corresponding to the image itself in a "frame", denoted by a "Start of Frame" segment header. The SOF header contains a part of the information required to decode the frame, and is structured according to the following table.</p>
<figure>
 <table>
  <thead><tr><th>Field</th><th>Value</th><th>Size (bytes)</th></tr></thead>
  <tbody>
   <tr><td>Precision (the number of pixels in a JPEG block)</td><td>8</td><td>1</td></tr>
   <tr><td>Image height</td><td>Up to 65535</td><td>2</td></tr>
   <tr><td>Image width</td><td>Up to 65535</td><td>2</td></tr>
   <tr><td>Components</td><td>Number of colour components</td><td>1</td></tr>
   <tr><td colspan="3">For each component (in a YUV-colour file, three)</td></tr>
   <tr><td>ID</td><td>Identifier for later use</td><td>1</td></tr>
   <tr><td>Sampling resolution</td><td>For later examination</td><td>1</td></tr>
   <tr><td>Quantisation table</td><td>For later examination</td><td>1</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Structure of the SOF header</figcaption>
</figure>
<p>As can be seen in the above table, some of the fields involve operations that we have not yet examined (the sampling resolution and the quantisation table for each component). For the purposes of completing the SOF segment handler, we can hold onto this information for later use.</p>
<p>A "frame" consists of the SOF header, and a number of "scans"; as the name implies, each scan is a pass over the full rectangle of the image. In an interlaced JPEG file for example, multiple scans would be present for the single frame, each of them having more resolution than the last; in a progressive JPEG file, there is just one scan containing all the information for the image. Since this series is concerned with building a decoder for progressive JPEG files, we'll focus on dealing with a single scan in the frame.</p>
<p>It turns out that the information required by Huffman decoding, in particular which of the <code>DHT</code> tables to use, is defined by each scan in the frame instead of by the frame itself. We'll look at the scan-level information in more detail in the next part of this series; for now, it's sufficient to decouple our representation of a colour component in the image from the <code>SOF</code> data, and define the exact metadata for a component later.</p>
<h2>Structure definitions</h2>
<p>With the information detailing the structure of an <code>SOF</code> header, it becomes relatively simple to build a segment parser to plug into our existing code. The only complication arises from the fact that multi-byte values in JPEG are stored in big-endian format, which may not necessarily be the host format for large integers. It's useful to have a set of definitions for transparently handling big-endian values, which is presented below.</p>
<samp>
 <h3>byteswap.h: Big-endian value handling macros</h3>
 <pre><s>/**
* Let's Build a JPEG Decoder
* Big-endian value handling macros
* Imran Nazar, May 2013
*/</s>

<kbd>#ifndef</kbd> __BYTESWAP_H_
<kbd>#define</kbd> __BYTESWAP_H_

<kbd>#if</kbd> __SYS_BIG_ENDIAN == <var>1</var>
<kbd>#   define</kbd> htoms(x) (x)
<kbd>#   define</kbd> htoml(x) (x)
<kbd>#   define</kbd> mtohs(x) (x)
<kbd>#   define</kbd> mtohl(x) (x)
<kbd>#else</kbd>
<kbd>#   define</kbd> htoms(x) (((x)&gt;&gt;<var>8</var>)|((x)&lt;&lt;<var>8</var>))
<kbd>#   define</kbd> htoml(x) (((x)&lt;&lt;<var>24</var>)|(((x)&amp;<var>0xFF00</var>)&lt;&lt;<var>8</var>)|(((x)&amp;<var>0xFF0000</var>)&gt;&gt;<var>8</var>)|((x)&gt;&gt;<var>24</var>))
<kbd>#   define</kbd> mtohs(x) (((x)&gt;&gt;<var>8</var>)|((x)&lt;&lt;<var>8</var>))
<kbd>#   define</kbd> mtohl(x) (((x)&lt;&lt;<var>24</var>)|(((x)&amp;<var>0xFF00</var>)&lt;&lt;<var>8</var>)|(((x)&amp;<var>0xFF0000</var>)&gt;&gt;<var>8</var>)|((x)&gt;&gt;<var>24</var>))
<kbd>#endif</kbd>

<kbd>#endif</kbd><s>//__BYTESWAP_H_</s></pre>
 <h3>jpeg.h: SOF header structures</h3>
 <pre><s>// Prevent padding bytes from creeping into structures</s>
<kbd>#define</kbd> PACKED <kbd>__attribute__</kbd>((<var>packed</var>))
 
<kbd>class</kbd> JPEG {
    <kbd>private</kbd>:
        <s>// Information in the SOF header</s>
        <kbd>struct</kbd> PACKED {
            u8  precision;
            u16 height;
            u16 width;
            u8  component_count;
        } sofHead;

        <kbd>typedef struct</kbd> PACKED {
            u8 id;
            u8 sampling;
            u8 q_table;
        } sofComponent;

        <s>// Internal information about a colour component</s>
        <kbd>typedef struct</kbd> PACKED {
            u8 id;
            <s>// There is likely to be more data here...</s>
        } Component;

        <s>// The set of colour components in the image</s>
        <kbd>std::vector</kbd><Component> components;

        <s>// The SOF segment handler</s>
        <kbd>int</kbd> SOF();
};</pre>
 <h3>jpeg.cpp: Passing control to the segment handler</h3>
 <pre><kbd>int</kbd> JPEG::parseSeg()
{
    ...

    <kbd>switch</kbd> (id) {
        <s>// The SOF segment defines the components and resolution
        // of the JPEG frame for a baseline Huffman-coded image</s>
        <kbd>case</kbd> <var>0xFFC0</var>:
            size = READ_WORD() - <var>2</var>;
            <kbd>if</kbd> (SOF() != size) {
                <kbd>printf</kbd>(<var>"Unexpected end of SOF segment\n"</var>);
                <kbd>return</kbd> JPEG_SEG_ERR;
            }
            <kbd>break</kbd>;

        ...
    }

    <kbd>return</kbd> JPEG_SEG_OK;
}</pre>
 <h3>jpeg.cpp: SOF segment handling</h3>
 <pre><kbd>int</kbd> JPEG::SOF()
{
    <kbd>int</kbd> ctr = <var>0</var>, i;

    <kbd>fread</kbd>(&amp;sofHead, <kbd>sizeof</kbd>(sofHead), <var>1</var>, fp);
    ctr += <kbd>sizeof</kbd>(sofHead);

    sofHead.width   = mtohs(sofHead.width);
    sofHead.height  = mtohs(sofHead.height);

    <kbd>printf</kbd>(<var>"Image resolution: %dx%d\n"</var>, sofHead.width, sofHead.height);

    <kbd>for</kbd> (i = <var>0</var>; i &lt; sofHead.component_count; i++) {
        sofComponent s;
        <kbd>fread</kbd>(&amp;s, <kbd>sizeof</kbd>(sofComponent), <var>1</var>, fp);
        ctr += <kbd>sizeof</kbd>(sofComponent);

        Component c;
        c.id = s.id;

        components.<kbd>push_back</kbd>(c);
    }

    <kbd>return</kbd> ctr;
}</pre>
</samp>
<h2>Next time: The Minimum Coded Unit</h2>
<p>As mentioned above, the image frame in a progressive JPEG file is encoded as a scan, composed of a series of blocks; depending on the sampling resolution of the components in the image, these blocks can be larger than the 8x8-pixel base block size of the JPEG algorithm. In the next part of this series, I'll examine the relationship between these larger units and the colour components of the image.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, May 2013.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Let&#039;s Build a JPEG Decoder: Huffman Tables</title>
 <link href="https://imrannazar.com/series/lets-build-a-jpeg-decoder/huffman-tables" rel="alternate" type="text/html" title="Let&#039;s Build a JPEG Decoder: Huffman Tables" />
 <id>https://imrannazar.com/series/lets-build-a-jpeg-decoder/huffman-tables</id>
 <summary>Various levels of compression and encoding are employed in the production of a JPEG file. The first step in decompressing an image is decoding the data, which is compressed with a variant of Huffman encoding. This article looks at the data attached to a JPEG file which allows the Huffman decoding to proceed.</summary>
 <category term="Series" />
 <published>Sun, 24 Feb 2013 22:06:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This article is part three of a series exploring the concepts and implementation of JPEG decoding; four parts are currently available, and others are expected to follow.</em>
 <ul>
  <li><a href="/series/lets-build-a-jpeg-decoder/concepts">Part 1: Concepts</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/structure">Part 2: File Structure</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/huffman-tables">Part 3: Huffman Tables</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/bitstreams">Part 4: Frames and Bitstreams</a></li>
 </ul>
</p>
<p><em>Download the code: <a href="http://imrannazar.com/content/files/jpegparse.zip">http://imrannazar.com/content/files/jpegparse.zip</a></em></p>
<p>In the previous part, I mentioned that most JPEG files employ an encoding technique on top of the image compression, in an attempt to remove any trace of redundant information from the image. The technique used by the most common JPEG encoding is an adaptation of one seen throughout the world of data compression, known as Huffman coding, so it's useful to explore in detail the structure and implementation of a Huffman decoder.</p>
<p>Because Huffman coding is the last thing performed by a JPEG encoder when saving an image file, it needs to be the first thing done by our decoder. This can be achieved in two ways:</p>
<ul>
 <li><strong>Reconstitution</strong>: The full image scan is decoded from its Huffman-coded state into a temporary placeholder, and further processing is performed on the temporary copy.</li>
 <li><strong>On-the-fly</strong>: The encoded image scan is processed one code at a time, and each JPEG block is handled when enough information is available.</li>
</ul>
<p>This article will take the second approach, to save memory and sacrifice time; full reconstitution can be implemented using the code built below in a very similar fashion.</p>
<h2>The Huffman algorithm</h2>
<p>The concept behind Huffman coding and other entropy-based schemes is similar to the concept behind the substitution cipher: each unique character in an input is transformed into a unique output character. The simplest example is the Caesar substitution, which can be represented in tabular form as follows:</p>
<samp>
 <pre>A =&gt; D
B =&gt; E
C =&gt; F
...
Y =&gt; B
Z =&gt; C

<kbd>This is an example of a Caesar cipher</kbd>
<var>Wklv lv dq hadpsoh ri d Fdhvdu flskhu</var></pre>
</samp>
<p>An improvement on the standard substitution cipher can be made by noting the relative frequency of characters in the input, and designing a table that contains shorter codes as substitutes for these characters, than for rarer ones. Taking a look at the frequency of letters in the above example, with their ASCII representations included, we can produce a table of increasing unique codes such as the following:</p>
<figure>
 <table>
  <thead><tr><th>Character</th><th>ASCII</th><th>Frequency</th><th>Code</th></tr></thead>
  <tbody>
   <tr><td>Space</td><td>00100000</td><td>7</td><td>00</td></tr>
   <tr><td>a</td><td>01100001</td><td>5</td><td>01</td></tr>
   <tr><td>e</td><td>01100101</td><td>4</td><td>100</td></tr>
   <tr><td>i</td><td>01101001</td><td>3</td><td>1010</td></tr>
   <tr><td>s</td><td>01110011</td><td>3</td><td>1011</td></tr>
   <tr><td>h</td><td>01101000</td><td>2</td><td>11000</td></tr>
   <tr><td>p</td><td>01110000</td><td>2</td><td>11001</td></tr>
   <tr><td>r</td><td>01110010</td><td>2</td><td>11010</td></tr>
   <tr><td>C</td><td>01000011</td><td>1</td><td>110110</td></tr>
   <tr><td>T</td><td>01010100</td><td>1</td><td>110111</td></tr>
   <tr><td>c</td><td>01100011</td><td>1</td><td>111000</td></tr>
   <tr><td>f</td><td>01100110</td><td>1</td><td>111001</td></tr>
   <tr><td>l</td><td>01101100</td><td>1</td><td>111010</td></tr>
   <tr><td>m</td><td>01101101</td><td>1</td><td>111011</td></tr>
   <tr><td>n</td><td>01101110</td><td>1</td><td>111100</td></tr>
   <tr><td>o</td><td>01101111</td><td>1</td><td>111101</td></tr>
   <tr><td>x</td><td>01110111</td><td>1</td><td>111110</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Frequency of characters in the string "This is an example of a Caesar cipher"</figcaption>
</figure>
<p>Substituting these codes for the characters in the original text, it can be seen how the encoded data is much smaller than the original.</p>
<samp>
 <pre><kbd>This is an example of a Caesar cipher</kbd>
01010100 01101000 01101001 01110011 00100000 01101001 01110011 00100000
01100001 01101110 00100000 01100101 01110111 01100001 01101101 01110000
01101100 01100101 00100000 01101111 01100110 00100000 01100001 00100000
01000011 01100001 01100101 01110011 01100001 01110010 00100000 01100011
01101001 01110000 01101000 01100101 01110010

110111 11000 1010 1011 00 1010 1011 00 01 111100 00 100 111110 01 111011
11011 111010 100 00 111101 111001 00 01 00 110110 01 100 1011 01 11010
00 111000 1010 11001 11000 100 11010

<kbd>54 68 69 73 20 69 73 20 61 6E 20 65 77 61 6D 70 6C 65 20 6F 66 20 61 20
43 61 65 73 61 72 20 63 69 70 68 65 72</kbd>
<var>DF 15 65 58 F8 4F 9E F7 D4 3D E4 4D 99 6E 8E 2B 38 9A</var></pre>
</samp>
<p>The main disadvantage of the Huffman coding method is that the table of codes needs to be stored alongside the compressed data: in the above example, the red string of encoded bytes would be meaningless without the corresponding frequency table. The table of codes and their corresponding characters can be recorded in full, but there is a more space-efficient way to save the codes, if attention is paid to the pattern of their occurrence. Two things are of note here: firstly that the codes increase in length, but also that within a group of the same length, codes are sequential. This means the code table can be written down as:</p>
<samp>
 <pre>2 codes of length two  , starting at 00
1 code  of length three, starting at 100
2 codes of length four , starting at 1010
3 codes of length five , starting at 11000
9 codes of length six  , starting at 110110</pre>
</samp>
<p>A careful eye on the codes themselves can yield further improvements on how much space it takes to record the encoding table. If we take a look at the codes in conjunction with the list of code length above, we can start counting as follows.</p>
<samp>
 <pre>00 (zero)
01 (one)
<s>Next code would be 10 (two)</s>
10<var>0</var> (four)
<s>Next code would be 101 (five)</s>
101<var>0</var> (ten)
1011 (eleven)
<s>Next code would be 1100 (twelve)</s>
1100<var>0</var> (twenty four)
11001 (twenty five)
11010 (twenty six)
<s>Next code would be 11011 (twenty seven)</s>
11011<var>0</var> (fifty four)
110111 (fifty five)
111000 (fifty six)
111001 (fifty seven)
111010 (fifty eight)
111011 (fifty nine)
111100 (sixty)
111101 (sixty one)
111110 (sixty two)</pre>
</samp>
<p>In every case, when the requisite number of codes has been counted for the given code length, all that is needed is to double the counter and continue for the next code length. In other words, there is no need to record the "starting at" part of the code lengths list above, since it can be inferred by starting at zero. The final code list therefore looks as follows.</p>
<samp>
 <pre>2 codes of length two
1 code  of length three
2 codes of length four
3 codes of length five
9 codes of length six

The above codes correspond to the following characters, in this order:
Space,a,e,i,s,h,p,r,C,T,c,f,l,m,n,o,x</pre>
</samp>
<h2>The JPEG DHT segment</h2>
<p>A JPEG file's Huffman tables are recorded in precisely this manner: a list of how many codes are present of a given length (between 1 and 16), followed by the meanings of the codes in order. This information is held in the file's "Define Huffman Table" (DHT) segments, of which there can be up to 32, according to the JPEG standard.</p>
<p>As seen above, data encoded by the Huffman algorithm ends up recorded as a series of codes wedged together in a bit-stream; this also applies to the image scan in a JPEG file. A simple routine for reading codes from the bit stream may look like this:</p>
<samp>
 <h3>Pseudocode for reading a Huffman-coded value</h3>
 <pre>Code = 0
Length = 0
Found = False

Do
    Code = Code &lt;&lt; 1
    Code = Code | (The next bit in the stream)
    Length = Length + 1
    If ((Length, Code) is in the Huffman list) Then
        Found = True
    End If
While Found = False</pre>
</samp>
<p>In order to facilitate this algorithm, the Huffman codes should be stored in a way that allows us to determine if a code is in the map at a given length. The canonical way to represent a Huffman code list is as a binary tree, where the sequence of branches defines the code and the depth of the tree tells us how long the code is. The C++ STL abstracts this out for us, into the <code>map</code> construct.</p>
<p>Since there are up to 32 possible Huffman tables that can be defined in a JPEG file, our implementation will require 32 <code>map</code>s to be available. It's also worth defining at this point how the DHT segment handler will be called by the <code>parseSeg</code> method developed in the previous part of this series.</p>
<samp>
 <h3>jpeg.h: DHT data definition</h3>
 <pre><kbd>class</kbd> JPEG {
    <kbd>private</kbd>:
        <s>// Defines a tuple of length and code, for use in the Huffman maps</s>
        <kbd>typedef std::pair</kbd>&lt;<kbd>int</kbd>, u16&gt; huffKey;

        <s>// The array of Huffman maps: (length, code) -&gt; value</s>
        <kbd>std::map</kbd>&lt;huffKey, u8&gt; huffData[<var>32</var>];

        <s>// DHT segment handler</s>
        <kbd>int</kbd> DHT();
};</pre>
 <h3>jpeg.cpp: Passing control to the segment handler</h3>
 <pre><kbd>int</kbd> JPEG::parseSeg()
{
    ...

    <kbd>switch</kbd> (id) {
        <s>// The DHT segment defines a Huffman table. The handler should
        // read exactly as many bytes from the file as are in the
        // segment; if not, something's gone wrong</s>
        <kbd>case</kbd> <var>0xFFC4</var>:
            size = READ_WORD() - <var>2</var>;
            <kbd>if</kbd> (DHT() != size) {
                <kbd>printf</kbd>(<var>"Unexpected end of DHT segment\n"</var>);
                <kbd>return</kbd> JPEG_SEG_ERR;
            }
            <kbd>break</kbd>;

        ...
    }

    <kbd>return</kbd> JPEG_SEG_OK;
}</pre>
 <h3>jpeg.cpp: DHT segment handler, builds a Huffman map</h3>
 <pre><kbd>int</kbd> JPEG::DHT()
{
    <kbd>int</kbd> i, j;

    <s>// A counter of how many bytes have been read</s>
    <kbd>int</kbd> ctr = <var>0</var>;

    <s>// The incrementing code to be used to build the map</s>
    u16 code = <var>0</var>;

    <s>// First byte of a DHT segment is the table ID, between 0 and 31</s>
    u8 table = <kbd>fgetc</kbd>(fp);
    ctr++;

    <s>// Next sixteen bytes are the counts for each code length</s>
    u8 counts[<var>16</var>];
    <kbd>for</kbd> (i = <var>0</var>; i &lt; <var>16</var>; i++) {
        counts[i] = <kbd>fgetc</kbd>(fp);
        ctr++;
    }

    <s>// Remaining bytes are the data values to be mapped
    // Build the Huffman map of (length, code) -&gt; value</s>
    <kbd>for</kbd> (i = <var>0</var>; i &lt; <var>16</var>; i++) {
        <kbd>for</kbd> (j = <var>0</var>; j &lt; counts[i]; j++) {
            huffData[table][huffKey(i + <var>1</var>, code)] = <kbd>fgetc</kbd>(fp);
            code++;
            ctr++;
        }
        code &lt;&lt;= <var>1</var>;
    }

    <s>// Once the map has been built, print it out</s>
    <kbd>printf</kbd>(<var>"Huffman table #%02X:\n"</var>, table);

    <kbd>std::map</kbd>&lt;huffKey, u8&gt;::<kbd>iterator</kbd> iter;
    <kbd>for</kbd> (iter = huffData[table].begin();
         iter != huffData[table].end();
         iter++
    ) {
        <kbd>printf</kbd>(<var>"    %04X at length %d = %02X\n"</var>,
            iter-&gt;first.second, iter-&gt;first.first, iter-&gt;second);
    }

    <kbd>return</kbd> ctr;
}</pre>
</samp>
<p>As with the previous part, the JPEG class can be instantiated with a filename; if this is done, the above code will produce output along the following lines:</p>
<samp>
 <pre>Found segment at file position 177: Huffman table
Huffman table #00:
    0000 at length 2 = 04
    0002 at length 3 = 02
    0003 at length 3 = 03
    0004 at length 3 = 05
    0005 at length 3 = 06
    0006 at length 3 = 07
    000E at length 4 = 01
    001E at length 5 = 00
    003E at length 6 = 08
    007E at length 7 = 09</pre>
</samp>
<h2>Next time: Reading the bitstream</h2>
<p>Once the Huffman maps have been built for a JPEG file, the image scan can be decoded for further processing. In the next part, I'll take a look at the Huffman decoding of the scan, in the wider context of reading blocks from the image and examining the process through which they are transformed.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Feb 2013.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Let&#039;s Build a JPEG Decoder: File Structure</title>
 <link href="https://imrannazar.com/series/lets-build-a-jpeg-decoder/structure" rel="alternate" type="text/html" title="Let&#039;s Build a JPEG Decoder: File Structure" />
 <id>https://imrannazar.com/series/lets-build-a-jpeg-decoder/structure</id>
 <summary>Aside from the concepts explored in the previous part of this series, the JPEG file format is composed of segments which encode the various portions of information needed to decode an image. This article implements a simple method of traversing the segments of a JPEG file.</summary>
 <category term="Series" />
 <published>Sun, 20 Jan 2013 11:30:18 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This article is part two of a series exploring the concepts and implementation of JPEG decoding; four parts are currently available, and others are expected to follow.</em>
 <ul>
  <li><a href="/series/lets-build-a-jpeg-decoder/concepts">Part 1: Concepts</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/structure">Part 2: File Structure</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/huffman-tables">Part 3: Huffman Tables</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/bitstreams">Part 4: Frames and Bitstreams</a></li>
 </ul>
</p>
<p><em>Download the code: <a href="http://imrannazar.com/content/files/jpegparse.zip">http://imrannazar.com/content/files/jpegparse.zip</a></em></p>
<p>In the previous part, I gave a brief overview of the techniques used by JPEG to compress an image. Before examining the detailed implementation of those techniques, it's useful to look at the overall structure of a JPEG file, for two reasons:</p>
<ul>
 <li>Some of the processes used by the encoder employ tables of values, which are stored alongside the image information itself, so it's sensible to retrieve these into memory before they're needed.</li>
 <li>We'll also need somewhere to put the implementation of the image decompression algorithm, and having a framework in place for that facilitates this.</li>
</ul>
<p>The implementation developed in this series of articles will be written in C++, but the constructs can be transplanted to a language of your choice with little additional complexity.</p>
<h2>Types of JPEG image</h2>
<p>It should be stated at this juncture that the implementation developed here will only apply to one common subset of all the possible types of JPEG image. Firstly, there are four types of compression supported by the standard:</p>
<ul>
 <li><strong>Baseline</strong>: The most common compression type, where all the image information is contained in one series of 8x8 blocks.</li>
 <li><strong>Extended Sequential</strong>: Most used in medical imaging, this type allows for more levels per pixel.</li>
 <li><strong>Progressive</strong>: Information from the frequency domain is written in a series of scans, the most important values for each block coming first in the file. This allows the whole image to be rendered at a low resolution, and the details filled in as the image downloads.</li>
 <li><strong>Lossless</strong>: A rare encoding based on a predicted difference between the target pixel and its surroundings.</li>
</ul>
<p>Further, there are two forms of encoding that are applied on top of the image compression, to further compress the file data:</p>
<ul>
 <li><strong>Huffman-based entropy</strong>: The image is made into a bit-stream, with the most common values encoded as short (2- or 3-bit) stream entries, and less common values recorded as longer strings of bits.</li>
 <li><strong>Arithmetic</strong>: A formerly patented encoding method, where the image data is represented as a series of probabilities of the values occurring, and combined into one fractional number.</li>
</ul>
<p>This series will implement an <strong>entropy-coded baseline</strong> JPEG decoder.</p>
<h2>File segments</h2>
<p>A JPEG file is made up of segments of varying length, each of which starts with a "marker" to denote which kind of segment it is. There are 254 possible types of segment, but only a few are found in the type of image we'll be decoding:</p>
<figure>
 <table>
  <thead><tr><th>Name</th><th>Short Name</th><th>Marker</th><th>Description</th><th>Length (bytes)</th></tr></thead>
  <tbody>
   <tr><td>Start of Image</td><td>SOI</td><td>FF D8</td><td>Delimits the start of the file</td><td>2</td></tr>
   <tr><td>Define Quantisation Table</td><td>DQT</td><td>FF DB</td><td>Values used by the decoder</td><td>69</td></tr>
   <tr><td>Define Huffman Table</td><td>DHT</td><td>FF C4</td><td>Values used by the decompressor</td><td>Variable</td></tr>
   <tr><td>Start of Frame</td><td>SOF</td><td>FF C0</td><td>Information for an entropy-coded baseline frame</td><td>10</td></tr>
   <tr><td>Start of Scan</td><td>SOS</td><td>FF DA</td><td>Encoded and compressed image bitstream</td><td>Variable</td></tr>
   <tr><td>End of Image</td><td>EOI</td><td>FF D9</td><td>Delimits the end of the file</td><td>2</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Segments present in an entropy-coded baseline JPEG file</figcaption>
</figure>
<p>Most of the different types of segment have a "length" value just after the marker, which denotes how long the segment is in bytes (including the length value); this can be used to skip over segments that a decoder doesn't know about. There are three exceptions to this general rule:</p>
<ul>
 <li><strong>SOI</strong> and <strong>EOI</strong>: Because these are more delimiters than markers, they consist only of the marker value.</li>
 <li><strong>SOS</strong>: The scan is a bitstream, and automatically "ends" when the image is fully coded. As such, there is no length written into the file for an SOS segment. There are two strategies for dealing with this: either we can assume the rest of the file is part of the scan, or we can read through the file looking for markers which would denote the start of a new segment.</p>
</ul>
<p>For this article, I'll assume the rest of the file is part of a scan if we run into an SOS segment, and skip straight to the EOI.</p>
<h2>Implementation: Listing the segments in a JPEG file</h2>
<p>As a first step, it makes sense to write a program to open a JPEG file, and run through it looking for segment markers. The structure of such a program can be expanded upon with implementation for processing of the different kinds of segments, and the mechanism for skipping over segments given their size can be used later to skip over the parts of the file which are non-essential to the decoding process.</p>
<p>Since the sizes of values in a JPEG file are specified in absolute terms of number of bytes, it's a good idea to abstract the basic integer types into types which refer to size. For this, we'll use a short header file.</p>
<samp>
 <h3>inttypes.h: Architecture-independent integer size definitions</h3>
 <pre><kbd>#ifndef</kbd> <var>__INTTYPES_H_</var>
<kbd>#define</kbd> <var>__INTTYPES_H_</var>

<kbd>typedef unsigned char</kbd>  u8;
<kbd>typedef unsigned short</kbd> u16;
<kbd>typedef unsigned int</kbd>   u32;

<kbd>typedef signed char</kbd>  s8;
<kbd>typedef signed short</kbd> s16;
<kbd>typedef signed int</kbd>   s32;

<kbd>#endif</kbd><s>//__INTTYPES_H_</s></pre>
</samp>
<p>The above file is set up for 32-bit compilation, but can be adapted if 64- or 16-bit code is required. The advantage of this is that references to integers in the JPEG decoder implementation itself can be agnostic of architecture, and simply refer to <code>u16</code> and other types defined here.</p>
<p>With these abstractions in place, the implementation of a segment listing is quite simple. Since we'll be building the decoding functionality into a class, it's worth defining the class itself at this time.</p>
<samp>
 <h3>jpeg.h: JPEG decoder class definition</h3>
 <pre><kbd>#ifndef</kbd> <var>__JPEG_H_</var>
<kbd>#define</kbd> <var>__JPEG_H_</var>

<kbd>#include</kbd> <var>"inttypes.h"</var>
<kbd>#include</kbd> <var>&lt;string&gt;</var>
<kbd>#include</kbd> <var>&lt;vector&gt;</var>
<kbd>#include</kbd> <var>&lt;map&gt;</var>
<kbd>#include</kbd> <var>&lt;stdio.h&gt;</var>

<s>// Macro to read a 16-bit word from file</s>
<kbd>#define</kbd> READ_WORD() ((<kbd>fgetc</kbd>(fp) &lt;&lt; <var>8</var>) | <kbd>fgetc</kbd>(fp))

<s>// Segment parsing error codes</s>
<kbd>#define</kbd> JPEG_SEG_ERR <var> 0</var>
<kbd>#define</kbd> JPEG_SEG_OK  <var> 1</var>
<kbd>#define</kbd> JPEG_SEG_EOF <var>-1</var>

<kbd>class</kbd> JPEG {
    <kbd>private</kbd>:
        <s>// Names of the possible segments</s>
        <kbd>std::string</kbd> segNames[<var>64</var>];

        <s>// The file to be read from, opened by constructor</s>
        <kbd>FILE</kbd> *fp;

        <s>// Segment parsing dispatcher</s>
        <kbd>int</kbd> parseSeg();

    <kbd>public</kbd>:
        <s>// Construct a JPEG object given a filename</s>
        JPEG(<kbd>std::string</kbd>);
};

<kbd>#endif</kbd><s>//__JPEG_H_</s></pre>
</samp>
<samp>
 <h3>jpeg.cpp: JPEG segment listing implementation</h3>
 <pre><kbd>#include</kbd> <var>"jpeg.h"</var>
<kbd>#include</kbd> <var>&lt;stdlib.h&gt;</var>
<kbd>#include</kbd> <var>&lt;string.h&gt;</var>
<kbd>#include</kbd> <var>&lt;math.h&gt;</var>

<s>//-------------------------------------------------------------------------
// Function: Parse JPEG file segment (parseSeg)
// Purpose: Retrieves 16-bit block ID from file, shows name</s>

<kbd>int</kbd> JPEG::parseSeg()
{
    <kbd>if</kbd> (!fp) {
        <kbd>printf</kbd>(<var>"File failed to open.\n"</var>);
        <kbd>return</kbd> JPEG_SEG_ERR;
    }

    u32 fpos = <kbd>ftell</kbd>(fp);
    u16 id = READ_WORD(), size;
    <kbd>if</kbd> (id &lt; <var>0xFFC0</var>)
    {   
        <kbd>printf</kbd>(<var>"Segment ID expected, not found.\n"</var>);
        <kbd>return</kbd> JPEG_SEG_ERR;
    }

    <kbd>printf</kbd>(
        <var>"Found segment at file position %d: %s\n"</var>,
        fpos, segNames[id-<var>0xFFC0</var>].<kbd>c_str</kbd>());

    <kbd>switch</kbd> (id) {
        <s>// The SOI and EOI segments are the only ones not to have
        // a length, and are always a fixed two bytes long; do
        // nothing to advance the file position</s>
        <kbd>case</kbd> <var>0xFFD9</var>:
            <kbd>return</kbd> JPEG_SEG_EOF;
        <kbd>case</kbd> <var>0xFFD8</var>:
            <kbd>break</kbd>;

        <s>// An SOS segment has a length determined only by the
        // length of the bitstream; for now, assume it's the rest
        // of the file less the two-byte EOI segment</s>
        <kbd>case</kbd> <var>0xFFDA</var>:
            <kbd>fseek</kbd>(fp, -<var>2</var>, <var>SEEK_END</var>);
            <kbd>break</kbd>;

        <s>// Any other segment has a length specified at its start,
        // so skip over that many bytes of file</s>
        <kbd>default</kbd>:
            size = READ_WORD();
            <kbd>fseek</kbd>(fp, size-<var>2</var>, <var>SEEK_CUR</var>);
            <kbd>break</kbd>;
    }

    <kbd>return</kbd> JPEG_SEG_OK;
}

<s>//-------------------------------------------------------------------------
// Function: Array initialisation (constructor)
// Purpose: Fill in arrays used by the decoder, decode a file
// Parameters: filename (string) - File to decode</s>

JPEG::JPEG(<kbd>std::string</kbd> filename)
{   
    <s>// Debug messages used by parseSeg to tell us which segment we're at</s>
    segNames[<var>0x00</var>] = <kbd>std::string</kbd>("Baseline DCT; Huffman");
    segNames[<var>0x01</var>] = <kbd>std::string</kbd>("Extended sequential DCT; Huffman");
    segNames[<var>0x02</var>] = <kbd>std::string</kbd>("Progressive DCT; Huffman");
    segNames[<var>0x03</var>] = <kbd>std::string</kbd>("Spatial lossless; Huffman");
    segNames[<var>0x04</var>] = <kbd>std::string</kbd>("Huffman table");
    segNames[<var>0x05</var>] = <kbd>std::string</kbd>("Differential sequential DCT; Huffman");
    segNames[<var>0x06</var>] = <kbd>std::string</kbd>("Differential progressive DCT; Huffman");
    segNames[<var>0x07</var>] = <kbd>std::string</kbd>("Differential spatial; Huffman");
    segNames[<var>0x08</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x09</var>] = <kbd>std::string</kbd>("Extended sequential DCT; Arithmetic");
    segNames[<var>0x0A</var>] = <kbd>std::string</kbd>("Progressive DCT; Arithmetic");
    segNames[<var>0x0B</var>] = <kbd>std::string</kbd>("Spatial lossless; Arithmetic");
    segNames[<var>0x0C</var>] = <kbd>std::string</kbd>("Arithmetic coding conditioning");
    segNames[<var>0x0D</var>] = <kbd>std::string</kbd>("Differential sequential DCT; Arithmetic");
    segNames[<var>0x0E</var>] = <kbd>std::string</kbd>("Differential progressive DCT; Arithmetic");
    segNames[<var>0x0F</var>] = <kbd>std::string</kbd>("Differential spatial; Arithmetic");
    segNames[<var>0x10</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x11</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x12</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x13</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x14</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x15</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x16</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x17</var>] = <kbd>std::string</kbd>("Restart");
    segNames[<var>0x18</var>] = <kbd>std::string</kbd>("Start of image");
    segNames[<var>0x19</var>] = <kbd>std::string</kbd>("End of image");
    segNames[<var>0x1A</var>] = <kbd>std::string</kbd>("Start of scan");
    segNames[<var>0x1B</var>] = <kbd>std::string</kbd>("Quantisation table");
    segNames[<var>0x1C</var>] = <kbd>std::string</kbd>("Number of lines");
    segNames[<var>0x1D</var>] = <kbd>std::string</kbd>("Restart interval");
    segNames[<var>0x1E</var>] = <kbd>std::string</kbd>("Hierarchical progression");
    segNames[<var>0x1F</var>] = <kbd>std::string</kbd>("Expand reference components");
    segNames[<var>0x20</var>] = <kbd>std::string</kbd>("JFIF header");
    segNames[<var>0x21</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x22</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x23</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x24</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x25</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x26</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x27</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x28</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x29</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2A</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2B</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2C</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2D</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2E</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x2F</var>] = <kbd>std::string</kbd>("[Reserved: application extension]");
    segNames[<var>0x30</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x31</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x32</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x33</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x34</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x35</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x36</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x37</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x38</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x39</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x3A</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x3B</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x3C</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x3D</var>] = <kbd>std::string</kbd>("[Reserved: JPEG extension]");
    segNames[<var>0x3E</var>] = <kbd>std::string</kbd>("Comment");
    segNames[<var>0x3F</var>] = <kbd>std::string</kbd>("[Invalid]");

    <s>// Open the requested file, keep parsing blocks until we run
    // out of file, then close it.</s>
    fp = <kbd>fopen</kbd>(filename.<kbd>c_str</kbd>(), <var>"rb"</var>);
    <kbd>if</kbd> (fp) {
        <kbd>while</kbd>(parseSeg() == JPEG_SEG_OK);
        <kbd>fclose</kbd>(fp);
    }
    <kbd>else</kbd> {
        <kbd>perror</kbd>(<var>"JPEG"</var>);
    }
}</pre>
</samp>
<p>When constructed with a file, an object of this JPEG class will provide output similar to the following.</p>
<samp>
 <h3>Output of JPEG segment listing</h3>
 <pre>Found segment at file position 0: Start of image
Found segment at file position 2: JFIF header
Found segment at file position 20: Quantisation table
Found segment at file position 89: Quantisation table
Found segment at file position 158: Baseline DCT; Huffman
Found segment at file position 177: Huffman table
Found segment at file position 208: Huffman table
Found segment at file position 289: Huffman table
Found segment at file position 318: Huffman table
Found segment at file position 371: Start of scan
Found segment at file position 32675: End of image</pre>
</samp>
<h2>Next time: Examining the encoding of a scan</h2>
<p>As can be seen above, the "scan" constitutes the majority of an entropy-coded baseline JPEG; since the entirety of the image data is encoded within the scan, this makes sense. Entropy coding is based on the Huffman compression algorithm, so in the next article I'll examine the parts of a JPEG file that provide the information needed to decode the scan from a bitstream into something usable for further processing.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jan 2013.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Let&#039;s Build a JPEG Decoder: Concepts</title>
 <link href="https://imrannazar.com/series/lets-build-a-jpeg-decoder/concepts" rel="alternate" type="text/html" title="Let&#039;s Build a JPEG Decoder: Concepts" />
 <id>https://imrannazar.com/series/lets-build-a-jpeg-decoder/concepts</id>
 <summary>This first part explores the concepts behind the compression techniques used by JPEG.</summary>
 <category term="Series" />
 <published>Sat, 05 Jan 2013 00:03:48 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This article is part one of a series exploring the concepts and implementation of JPEG decoding; four parts are currently available, and others are expected to follow.</em>
 <ul>
  <li><a href="/series/lets-build-a-jpeg-decoder/concepts">Part 1: Concepts</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/structure">Part 2: File Structure</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/huffman-tables">Part 3: Huffman Tables</a></li>
  <li><a href="/series/lets-build-a-jpeg-decoder/bitstreams">Part 4: Frames and Bitstreams</a></li>
 </ul>
</p>
<p>Build a JPEG decoder? Whatever for, when we have so many of them already?</p>
<p>JPEG is something we all take for granted: most of the Web comprises pictures transmitted as JPEG files, and video files based on JPEG technology. As it turns out, the concepts that lie behind these images span nearly two hundred years of mathematics and computing theory, and going from the raw file to an image takes a bunch of interesting work.</p>
<h2>At the core: frequency analysis</h2>
<p>In <em><a href="/articles/introduction-to-compression">An Introduction to Compression</a></em>, I looked at the difference between "lossless" and "lossy" compression: the difference between the two methods is that lossless compression preserves all the inherent information of the input, whereas lossy compression throws much of it away. Throwing information away only works when it can be deemed unnecessary for proper handling of the file; this would never be the case for a computer program, for example, where every byte is a statement that must be retained.</p>
<p>Images or videos, and their cousins in the audio world, rely on <em>perception</em> to work out what needs to be thrown away: just as the human ear can only distinguish sounds in a particular region of frequencies, the human eye has a particular resolution and any colour changes that happen within a very short distance are essentially invisible. Resolution can also be thought of as "visual frequency", and can be manipulated in much the same way as sound wave frequency or other kinds of wave.</p>
<p>It follows that a chunk of sound or a piece of an image can be compressed by removing those parts of the frequency range that are outside the human experience: those frequency ranges that we don't care about, without which the essence isn't lost. There are three steps to doing that:</p>
<ul>
 <li><strong>Transform the sample</strong>: Sound waves are changes of sound level through time, and images are changes of colour through two dimensions of space. We need somehow to change these into frequency representations of themselves, through a transformation.</li>
 <li><strong>Band-pass</strong>: Once we're in the frequency domain, we need to cut out the section, or band, of frequencies that interests us. The technical term for this is a "band-pass filter".</li>
 <li><strong>Inverse transform</strong>: Our newly reduced signal can then be sent backwards through the transformation, resulting in a sound or image that's had its excess information stripped.</li>
</ul>
<p>The transformation use is derived from the <a href="http://en.wikipedia.org/wiki/Fourier_transform">Fourier transform</a>, which takes an integratable mathematical function <em>f(x)</em> and generates an equation <em>f(s)</em> for a frequency spectrum. The Fourier transform only works with continuous ranges of numbers, and extends from negative infinity to positive infinity; this makes it unusable for digital transformations like those we need here. Instead, a discrete version of the Fourier transform is used: the MP3 and JPEG techniques use the <a href="http://en.wikipedia.org/wiki/Discrete_cosine_transform">discrete cosine transform</a> (DCT) to change a set of data values into an equivalent set of frequencies.</p>
<p>Two examples of the compression process are presented in the following figures: first for a short sound sample.</p>
<figure class="invertable">
 <img src="/content/img/jpeg-concepts-bandpass.png" alt="Sound bandpass filtering">
 <figcaption>Figure 1: Chorus riff, "More Than a Feeling" (Boston, 1976)<br>Encoded to 40kbps MPEG audio Layer 3<br>Frequency analysis courtesy of <a href="http://artalabs.hr/">ARTA</a> for Windows, by Ivo Mateljan</figcaption>
</figure>
<p>The below figure represents the same process as above, but applied in two dimensions of space as opposed to one of time. It is generally considered inefficient to transform the entire image into a visual frequency domain at once, so the JPEG algorithm transforms blocks of eight pixels square at a time.</p>
<figure class="invertable">
 <img src="/content/img/jpeg-concepts-blockwise.png" alt="Image bandpass filtering">
 <figcaption>Figure 2: Icon from the <a href="http://dryicons.com/free-icons/preview/shine-icon-set/">DryIcons Shine set</a><br>Encoded to JPEG, q=25%</figcaption>
</figure>
<p>In Figure 2, the right-hand set of images show the DCT and its filtered version. The most important figure in each 8x8 block is the "DC component" in the top-left, which determines the base level for the whole block. Values to the right of this give information as to how often variances happen horizontally, and conversely values below the DC component provide vertical frequency information. It follows that values in the bottom-right of a DCT block describe the highest-fidelity changes in the image, and that filtering consists of drawing a diagonal across each block and retaining the top portion, throwing away the information regarding high-fidelity changes.</p>
<h2>Colour spaces and downsampling</h2>
<p>JPEG makes use of the fact that the human eye has a maximum resolution when it comes to visual changes. Another feature of the eye is that it is less sensitive to changes in colour than in brightness: the frequency-sensitive "cone" cells of the retina occur at a lower density than the simpler frequency-agnostic "rods", which means a lower visual resolution for colour.</p>
<p>It is possible for images to be further compressed by utilising this information, reducing the amount of information used to encode colour values in relation to brightness. Unfortunately, the traditional additive colour space of red/green/blue used by computer and television displays retains no information about relative brightness and colour saturation; in order to retrieve this information RGB values must be transformed to another colour model.</p>
<p>The JPEG format most commonly uses Y'CbCr colour, where <strong>Y'</strong> denotes the luminance of a particular pixel, and the <strong>Cb</strong> and <strong>Cr</strong> components describe the amount of chrominance on two axes, corresponding to percentages of blue and of red. Transformations from RGB pixel values to Y'CbCr act as a rotation between the cube of all possible RGB values and the cube of possible luminance/chrominance values, as shown in Figure 3.</p>
<figure class="invertable">
 <img src="/content/img/jpeg-concepts-yuv.png" alt="YCbCr and RGB cubes">
 <figcaption>Figure 3: The RGB cube, rotated within the Y'CbCr cube<br>From the <a href="http://software.intel.com/sites/products/documentation/hpc/ipp/ippi/">Intel Integrated Performance Primitives manual</a></figcaption>
</figure>
<p>Once transformed to Y'CbCr, the chrominance channels are separated out and can be manipulated. In this case, "downsampling" is employed: the resolution of the colour channels is halved in both dimensions, such that one "block" of colour information covers the equivalent area of four luminance blocks. In Figure 4, the colour channels have been downsampled by this ratio: it can be seen that the <strong>Y'</strong> channel is the most important for the integrity of the image, and thus its resolution remains high.</p>
<figure>
 <img src="/content/img/jpeg-concepts-channels.png" alt="YCbCr channels">
 <figcaption>Figure 4: A JPEG image broken into its Y'CbCr channels, with chrominance downsampling</figcaption>
</figure>
<p>For the remainder of this series of articles, bidirectional downsampling of the type shown here will be assumed: most JPEG images on the Web employ this colour compression, so it's useful to explore. Because of the reduction in resolution, the previously mentioned eight-pixel square used by the JPEG algorithm becomes a minimum unit size of 16 pixels square, with four 8x8 luminance blocks accompanying one block for each axis of colour information.</p>
<h2>Next time: The file format</h2>
<p>JPEG files store additional information alongside the encoded image: lookup tables to be used by the decoding process, comments and resolution information. In part two, I'll take a look at the segments that make up a JPEG file, and how to hold onto some of the information provided for use by the decoding implementation of subsequent parts.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jan 2013.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">svn branchlist: Print branch names for multiple repos</title>
 <link href="https://imrannazar.com/hacks/svn-branchlist" rel="alternate" type="text/html" title="svn branchlist: Print branch names for multiple repos" />
 <id>https://imrannazar.com/hacks/svn-branchlist</id>
 <summary>Ever run into a codebase with multiple Subversion repositories, where you just wanted to find out which branch they were all on without tediously cd&#039;ing into each working copy?</summary>
 <category term="Quick Hacks" />
 <published>Wed, 03 Oct 2012 11:06:47 +0000</published>
 <content type="text/html"><![CDATA[
   <p>I sometimes run into the situation where I'm working on multiple related Subversion repositories, and all their working copies are in a "repository root" on my drive. With these repos being switched to different branches, it became tedious to flip through each one to find which branch they were attached to.</p>
<p>Like any lazy programmer, I automated the process into a Bash script.</p>
<samp>
 <h3>svnbr: A script to print the current branch name of multiple Subversion working copies</h3>
 <pre><s>#!/bin/bash</s>
REPOROOT=<var>"/home/inazar/code"</var>
PREFIX=<var>"foo-"</var>
POSTFIX=<var>"-bar"</var>

t=`<kbd>mktemp</kbd> /tmp/svnbr_XXXXX`
<kbd>pushd</kbd> . &gt; /dev/null
<kbd>cd</kbd> $REPOROOT
<kbd>for</kbd> a <kbd>in</kbd> `<kbd>find</kbd> . -maxdepth 1 -name <var>"$PREFIX*$POSTFIX"</var>`; <kbd>do</kbd>
        <kbd>cd</kbd> $a
        b=`<kbd>svn</kbd> info 2&gt; /dev/null | <kbd>grep</kbd> URL | <kbd>awk</kbd> -F<var>'/'</var> <var>'{print $NF}'</var>`
        c=${a%$POSTFIX}
        c=${c#$PREFIX}
        c=${c:2}
        d=<var>""</var>

        <s># Caveat: Display will fall over with repo names past 16 chars</s>
        [[ ${#c} -lt <var>8</var> ]] &amp;&amp; d=<var>"\t"</var>
        <kbd>echo</kbd> -e <var>"$c\t$d $b"</var> &gt;&gt; $t
        <kbd>cd</kbd> ..
<kbd>done</kbd>
<kbd>popd</kbd> &gt; /dev/null
<kbd>sort</kbd> $t
<kbd>rm</kbd> $t</pre>
</samp>
 ]]></content>
</entry>
<entry>
 <title type="html">How Emulators Work: a presentation</title>
 <link href="https://imrannazar.com/hacks/how-emulators-work" rel="alternate" type="text/html" title="How Emulators Work: a presentation" />
 <id>https://imrannazar.com/hacks/how-emulators-work</id>
 <summary>At deviantART&#039;s technology team meetup in France (&#039;Breadlands 2012&#039;), I gave a short Ignite talk distilling the first three articles in the Gameboy Emulation in Javascript. The slides from that talk are now available here.</summary>
 <category term="Quick Hacks" />
 <published>Wed, 27 Jun 2012 10:38:40 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The following 17 slides constitute an Ignite talk given at <a href="http://www.deviantart.com/">deviantART</a>'s technology team meetup in France, earlier this month.</p>
<figure>
 <img src="/content/img/jsgb-slides/slide01-sml.png" alt="Slide 01: Title">
 <figcaption>I've written a couple of emulation cores in my time, and people often ask me how computer emulators work. Well, let's take an example...</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide02-sml.png" alt="Slide 02: A Simple 8-bit Computer">
 <figcaption>Doesn't look like a computer: there's no keyboard, no hard disk. But all the central components are there: processor, memory, keypad input, screen.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide03-sml.png" alt="Slide 03: The Gameboy Memory Model">
 <figcaption>This is how the Gameboy looks on the inside: A processor talks, through a memory interface, to various memories. The program sits in one of those memories, but what _is_ the program?</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide04-sml.png" alt="Slide 04: Programs: A Stream of Numbers">
 <figcaption>All a program is, is a set of numbers. Each number means something to the processor, and it goes through a simple construct to work out what the number means.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide05-sml.png" alt="Slide 05: Basic Operation of a CPU">
 <figcaption>Take a number from the "current location", work out what it means, do that. Fetch, Decode, Execute. How does the CPU know what the "current location" is, though?</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide06-sml.png" alt="Slide 06: The Current State">
 <figcaption>As long as the CPU's running, it holds onto a few state variables. One of those is the "current location", or where to find the next instruction. There are others, to help with calculation.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide07-sml.png" alt="Slide 07: That Stream of Numbers Again">
 <figcaption>Once we have a number, we decode it. Most instructions will either change one of the state variables, or change a piece of memory; some might request more numbers from the program to fully decode.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide08-sml.png" alt="Slide 08: TANSTAAFL: Execution Times">
 <figcaption>One thing to keep in mind is that none of this is free: it all takes time. For now, that's unimportant, but make a mental note of it.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide09-sml.png" alt="Slide 09: The CPU as a Stateful Machine">
 <figcaption>To implement the Fetch/Decode/Execute cycle, the CPU needs a few distinct blocks of functionality, and an interface to memory in order to get more program, and hold onto results.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide10-sml.png" alt="Slide 10: The CPU, Emulated">
 <figcaption>To emulate the cycle, we tear each block out and replace it with JavaScript: a big switch() to decode, discrete functions to execute routines and update the state, and a plain object to hold the state.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide11-sml.png" alt="Slide 11: That Stream of Numbers, Emulated">
 <figcaption>So those instructions we saw earlier, they become JS. Notice how each instruction changes PC, the "current location", so it points at the next one in the line.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide12-sml.png" alt="Slide 12: The Emulated Gameboy Memory Model">
 <figcaption>That's the CPU: the memories are easy to emulate. They're just huge arrays. The interface object, "MMU", takes care of mapping out which memory the CPU's looking to talk to; that's generally another switch().</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide13-sml.png" alt="Slide 13: Other Modules of the Gameboy">
 <figcaption>All well and good, but the CPU's plugging away without showing anything. Ideally, we need to emulate the other pieces: graphics, sound, keypad. The most important, of course, is graphics.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide14-sml.png" alt="Slide 14: The Gameboy LCD (as a CRT)">
 <figcaption>The Gameboy has 144 lines on its screen, and the graphics chip treats the screen like a traditional tube: scan a line, fly back to the left, at the bottom take a long time to fly back to the top-left.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide15-sml.png" alt="Slide 15: Timings of the Gameboy LCD">
 <figcaption>Each of those scanlines, and blanking periods, has a precise time for how long it should take. But we're emulating the whole system, at a low precision.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide16-sml.png" alt="Slide 16: The CPU as a Clock Source">
 <figcaption>Remember these from earlier; they allow the CPU to act as "emulated time". We can count the CPU instruction times, and know when to draw a GPU's scanline.</figcaption>
</figure>
<figure>
 <img src="/content/img/jsgb-slides/slide17-sml.png" alt="Slide 17: Bringing the Two Together: Dispatch">
 <figcaption>We end up with a central dispatcher, which runs the CPU until it's time to switch GPU mode. And that's a (very) basic introduction to how emulators work.</figcaption>
</figure>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Behind the Mirror</title>
 <link href="https://imrannazar.com/scifi/behind-the-mirror" rel="alternate" type="text/html" title="Sci-fi Shorts: Behind the Mirror" />
 <id>https://imrannazar.com/scifi/behind-the-mirror</id>
 <summary>The day after the night before, a hungover flatmate notices that the wall mirror looks a bit strange. Speculative flash fiction.</summary>
 <category term="Original Writings" />
 <published>Tue, 24 Jan 2012 15:02:50 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Coffee was John's friend this morning. A bottle of Everclear had vanished somewhere between 8pm and midnight yesterday, and it was likely that it'd gone into him: since his head felt three times as large as it should, that seemed to place him at the scene of the theft.</p>
<p>Another espresso later, John took to the task of surveying the damage. It wasn't too bad, actually: Ryan had been even more trashed, and had managed to spray the contents of the bookcase around the room. John found Tolkien behind the TV, and Dostoyevsky perched miraculously above the wall clock, but Asimov would have to wait until the pile of beer cans could be examined more closely. John wasn't feeling up to that right now.</p>
<p>It looked like one thing was broken: the frame around the mirror. Evidently, a coffee table had been lobbed at that wall at some point (a missing chunk of plaster, and the fine coating of gypsum on the table in question, attested to that). Amazingly, the mirror wasn't broken: the wooden frame had collapsed and lay around it, but the mirror itself was intact on the floor.</p>
<p>John picked up the glass, and felt that there was a slightly serrated edge on the bottom. He'd never seen the back of the mirror before, and looking closer at it revealed an intricate pattern of lines, converging on a group of 20-some parallel rows corresponding to the bumps along the bottom. John had seen something like this only a few times before, and every time it was something quite special.</p>
<p>An electronic circuit.</p>
<p>Obviously, no clue was forthcoming about what the circuit contained, or the secrets encoded within any solid-state memories that might be on the back of the mirror. John thought about enlisting Ryan's help to try to decipher the tracings, but he was still knocked out on the sofa, and would probably remain there for much of the morning.</p>
<p>John would have to go outside for this one.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Steganography with Brainfuck</title>
 <link href="https://imrannazar.com/articles/steganography-with-brainfuck" rel="alternate" type="text/html" title="Steganography with Brainfuck" />
 <id>https://imrannazar.com/articles/steganography-with-brainfuck</id>
 <summary>There are a number of techniques for encrypting or hiding information within an image, including the concept of hiding a program within the image which itself prints the secret information. This article explores the feasibility of encoding a Brainfuck program within the bitmap data of an image, with a detailed run-through of a simple example.</summary>
 <category term="Articles" />
 <published>Sat, 12 Nov 2011 18:16:58 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Steganography is a name given for a set of techniques where the targeted message is hidden inside other data, most often in the context of an image in some form. Common forms of steganography include deviations in the level of individual pixels, or changes to the low-level noise components of the image. In this article, I'll look at a technique that produces an image which is also a program, which can be run to produce the targeted message.</p>
<p>In order to keep the examples here simple, I've sought a form of program that has a simple instruction set. Many processors have a simple instruction set: the 6502 has around 150 unique codes in its architecture, which can be reduced further with careful selection of instructions. However, having <a href="/articles/trainfuck">written about Brainfuck before</a>, it seems the logical choice: eight instructions, each with a unique code, and all other codes are ignored during execution.</p>
<p>The program to be encoded, then, is as follows:</p>
<samp>
 <h3>Message before encoding</h3>
 <pre>&gt;&gt;++++++++[&lt;+++[&lt;+++++&gt;-]&gt;-]&lt;&lt;[&gt;+&gt;+&gt;+&gt;+&gt;+&lt;&lt;&lt;&lt;&lt;-]++++++++[&gt;-&gt;--&gt;
---&gt;----&gt;-----&lt;&lt;&lt;&lt;&lt;-]&lt;++++[&gt;++++++++&lt;-]&gt;&gt;&gt;&gt;&gt;&gt;++++.&lt;&lt;&lt;.&gt;+++++.&lt;&lt;
&lt;.&gt;&gt;+++++.++.-.---.&gt;.&lt;&lt;+++++++++.&lt;.&gt;&gt;--.&lt;------.&lt;.&gt;&gt;.+++++.&lt;&lt;.&gt;
+.&gt;------.&gt;.&lt;&lt;&lt;.&gt;&gt;&gt;-.&lt;+.&lt;-.&gt;-.&lt;++++.&gt;&gt;---.&lt;&lt;----.&gt;.&gt;++++.&lt;&lt;-.

The monkey is in the dishwasher</pre>
</samp>
<h2>Encoding program code into pixels</h2>
<p>In order for the program to be converted to an image, the first step is to take the program as a stream of numbers. In Brainfuck, the eight operators can be treated as eight numbers to be inserted into a stream:</p>
<figure>
 <table>
  <tr><th>+</th><td>0x2B</td><th>-</th><td>0x2D</td></tr>
  <tr><th>[</th><td>0x5B</td><th>]</th><td>0x5D</td></tr>
  <tr><th>&lt;</th><td>0x3C</td><th>&gt;</th><td>0x3E</td></tr>
  <tr><th>.</th><td>0x2E</td><th>,</th><td>0x2C</td></tr>
 </table>
 <figcaption>Table 1: Character values for the Brainfuck operators</figcaption>
</figure>
<p>Hiding these values within image data would be difficult if the data were full-colour (24- or 32-bit), since the colour component would need to correspond exactly at a given point in the image. Instead of using full-colour images, it makes more sense to use palette-based images, where an 8-bit palette index refers to a table of colours defined beforehand.</p>
<p>A simple example of palette data would be a graded greyscale image of sixteen shades, like the one below:</p>
<figure>
 <img src="/content/img/bf-bmp-original.png" alt="Lena in greyscale">
 <figcaption>Figure 1: Lena, in sixteen-shade greyscale</figcaption>
</figure>
<p>If this image is produced in a standard fashion, a palette of sixteen entries and 240 blanks is saved alongside the image. By expanding the palette entries used to the maximum allotted number of 256, it's possible to use the extra entries for hiding information:</p>
<figure>
 <table>
  <tr><th></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th></tr>
  <tr>
   <th>0</th>
   <td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td>
   <td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td>
   <td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td>
   <td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td><td style="background:#000"></td>
  </tr>
  <tr>
   <th>1</th>
   <td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td>
   <td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td>
   <td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td>
   <td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td><td style="background:#111"></td>
  </tr>
  <tr>
   <th>2</th>
   <td style="background:#222"></td><td style="background:#222"></td><td style="background:#222"></td><td style="background:#222"></td>
   <td style="background:#222"></td><td style="background:#222"></td><td style="background:#222"></td><td style="background:#222"></td>
   <td style="background:#222"></td><td style="background:#222"></td><td style="background:#222"></td><td style="background:#f00;color:white">+</td>
   <td style="background:#fff">,</td><td style="background:#f80;color:white">-</td><td style="background:#0f0">.</td><td style="background:#222"></td>
  </tr>
  <tr>
   <th>3</th>
   <td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td>
   <td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td>
   <td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td><td style="background:#333"></td>
   <td style="background:#f0f;color:white">&lt;</td><td style="background:#333"></td><td style="background:#08f;color:white">&gt;</td><td style="background:#333"></td>
  </tr>
  <tr>
   <th>4</th>
   <td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td>
   <td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td>
   <td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td>
   <td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td><td style="background:#444"></td>
  </tr>
  <tr>
   <th>5</th>
   <td style="background:#555"></td><td style="background:#555"></td><td style="background:#555"></td><td style="background:#555"></td>
   <td style="background:#555"></td><td style="background:#555"></td><td style="background:#555"></td><td style="background:#555"></td>
   <td style="background:#555"></td><td style="background:#555"></td><td style="background:#555"></td><td style="background:#ff0;">[</td>
   <td style="background:#555"></td><td style="background:#0ff">]</td><td style="background:#555"></td><td style="background:#555"></td>
  </tr>
  <tr>
   <th>6</th>
   <td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td>
   <td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td>
   <td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td>
   <td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td><td style="background:#666"></td>
  </tr>
  <tr>
   <th>7</th>
   <td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td>
   <td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td>
   <td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td>
   <td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td><td style="background:#777"></td>
  </tr>
  <tr>
   <th>8</th>
   <td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td>
   <td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td>
   <td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td>
   <td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td><td style="background:#888"></td>
  </tr>
  <tr>
   <th>9</th>
   <td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td>
   <td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td>
   <td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td>
   <td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td><td style="background:#999"></td>
  </tr>
  <tr>
   <th>A</th>
   <td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td>
   <td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td>
   <td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td>
   <td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td><td style="background:#AAA"></td>
  </tr>
  <tr>
   <th>B</th>
   <td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td>
   <td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td>
   <td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td>
   <td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td><td style="background:#BBB"></td>
  </tr>
  <tr>
   <th>C</th>
   <td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td>
   <td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td>
   <td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td>
   <td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td><td style="background:#CCC"></td>
  </tr>
  <tr>
   <th>D</th>
   <td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td>
   <td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td>
   <td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td>
   <td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td><td style="background:#DDD"></td>
  </tr>
  <tr>
   <th>E</th>
   <td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td>
   <td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td>
   <td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td>
   <td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td><td style="background:#EEE"></td>
  </tr>
  <tr>
   <th>F</th>
   <td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td>
   <td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td>
   <td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td>
   <td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td><td style="background:#FFF"></td>
  </tr>
 </table>
 <figcaption>Table 2: Sixteen-shade greyscale palette, with Brainfuck operators indicated</figcaption>
</figure>
<p>As can be seen above, each row of the palette is the same shade of grey, except where the Brainfuck operators map onto the palette. By changing arbitrary pixels in the image, it's possible to replace any given #2-grey pixel with, for example, a <code>+</code> operator without changing the row of the palette used. Shifting pixel values along the palette row in this fashion allows us to change the value without changing the look of the image.</p>
<p>Before applying this concept to the example image in Figure 1, it's important to consider the type of image needed for this to work.</p>
<h2>Uncompressed images: the BMP format</h2>
<p>The major issue presented by image formats is that of compression: in order to make the image file size smaller, various methods of compression can be used to translate areas of similarity in the image to a much smaller amount of data than that represented by the raw image. Of course, when this is done the resultant compressed data bears no superficial relation to the raw image data; attempting to encode a Brainfuck program into the compressed data stream is beyond the scope of this article.</p>
<p>Instead, I'll be focussing on the raw image data itself; storage of the raw data can be achieved through an uncompressed data format such as TIFF. Examples of uncompressed 8-bit palette image formats include BMP and PCX; the former will be used here, due to its prevalence as a major image file format. When used as an uncompressed 8-bit format, the structure of a BMP file is as follows:</p>
<figure>
 <table>
  <tr><th>Field</th><th>Size (bytes)</th><th>Value</th></tr>
  <tr><td>Signature</td><td>2</td><td>"BM"</td></tr>
  <tr><td>File size</td><td>4</td><td>Size of the full BMP</td></tr>
  <tr><td>Reserved</td><td>4</td><td>0x00000000</td></tr>
  <tr><td>Data offset</td><td>4</td><td>Offset of the pixel array</td></tr>
  <tr><th colspan="3">BITMAPINFOHEADER</th></tr>
  <tr><td>Header size</td><td>4</td><td>0x00000028</td></tr>
  <tr><td>Image width</td><td>4</td><td>Width of the image in pixels</td></tr>
  <tr><td>Image height</td><td>4</td><td>Height of the image in pixels</td></tr>
  <tr><td>Colour planes</td><td>2</td><td>0x0001</td></tr>
  <tr><td>Color depth</td><td>2</td><td>0x0008</td></tr>
  <tr><td>Compression method</td><td>4</td><td>0x00000000</td></tr>
  <tr><td>Uncompressed image size</td><td>4</td><td>Width * height * bytes-per-pixel</td></tr>
  <tr><td>Horizontal DPM</td><td>4</td><td>Pixels per metre, horizontal</td></tr>
  <tr><td>Vertical DPM</td><td>4</td><td>Pixels per metre, vertical</td></tr>
  <tr><td>Colours used</td><td>4</td><td>Number of unique colours</td></tr>
  <tr><td>Important colours</td><td>4</td><td>Number of important colours</td></tr>
  <tr><th colspan="3">Colour table (256 entries)</th></tr>
  <tr><td>Colour</td><td>4</td><td>RGBA value</td></tr>
  <tr><th colspan="3">Pixel data, 1 byte per pixel</th></tr>
 </table>
 <figcaption>Table 3: BMP file structure (all numeric fields are little-endian)</figcaption>
</figure>
<p>The end result of this process is to produce a bitmap file that can be run as a Brainfuck program; to that end, we must be careful that the header data and colour table don't contain Brainfuck operators that may corrupt the initial state of the program. This is, fortunately, relatively easy: all that is needed is to pick an image width and height that don't contain an operator within the byte values, and the rest should automatically fall into place.</p>
<p>One other quirk of the BMP format is the order in which pixel data is stored. Most image formats treat the first row as the top row, in accordance with computer graphics principles; BMP lines up with mathematical graphing principles, and treats the bottom row as the first.</p>
<figure class="invertable">
 <img src="/content/img/bf-bmp-graph.png" alt="Position of the first row">
 <figcaption>Figure 2: Position of the rows in a BMP</figcaption>
</figure>
<p>This means that the Brainfuck operators need to be encoded into the image starting at the bottom, running left-right, then moving up to the next row. By examining each operator in the program in turn, and finding the next appropriate pixel (of the same row in the palette) to replace, the following result is obtained.</p>
<figure>
 <img src="/content/img/bf-bmp-encoded.png" alt="Encoded Lena">
 <figcaption>Figure 3: Lena, encoded with the targeted message, at 400% zoom</figcaption>
</figure>
<p>Once the appropriate pixels have been replaced with versions shifted along the palette row, the palette can be amended to set the Brainfuck operators to the same colour as the rest of the row in which they reside. Doing this, and producing an uncompressed bitmap of the result, provides the following.</p>
<figure>
 <div style="width:264px;height:128px;margin:0 auto">
  <img src="/content/img/bf-bmp-original.png" alt="Original Lena" style="float:left">
  <img src="/content/img/bf-bmp-final.bmp" alt="Final encoded Lena" style="float:right">
  <div style="clear:both"></div>
 </div>
 <figcaption>Figure 4: The original image, and the image encoded with the target message</figcaption>
</figure>
<p>Running the bitmap image, shown on the right, through a Brainfuck interpreter results in the targeted message being revealed.</p>
<samp>
 <h3>PHP Brainfuck interpreter</h3>
 <pre>&lt;?php
<kbd>list</kbd>($c, $i) = <kbd>split</kbd>(<var>'!'</var>, <kbd>file_get_contents</kbd>($_SERVER[<var>'argv'</var>][<var>1</var>]));
$c = <kbd>preg_replace</kbd>(<var>'#[^\[\]\&lt;\&gt;,.+-]#'</var>, <var>""</var>, $c);
$p = $v = <var>0</var>;
<kbd>eval</kbd>(<kbd>strtr</kbd>($c, <kbd>array</kbd>(
    <var>"]"</var> =&gt; <var>"}"</var>,
    <var>"["</var> =&gt; <var>'while($m[$p]){'</var>,
    <var>"+"</var> =&gt; <var>'$m[$p]++;'</var>,
    <var>"-"</var> =&gt; <var>'$m[$p]--;'</var>,
    <var>"&gt;"</var> =&gt; <var>'$p++;'</var>,
    <var>"&lt;"</var> =&gt; <var>'$p--;'</var>,
    <var>","</var> =&gt; <var>'if(strlen($i)&gt;$v)$m[$p]=ord($i[$v++]);'</var>,
    <var>"."</var> =&gt; <var>'echo chr($m[$p]);'</var>
)));
?&gt;</pre>
 <h3>Sample result</h3>
 <pre>$ php -f brainfuck.php http://imrannazar.com/content/img/bf-bmp-final.bmp
The monkey is in the dishwasher$</pre>
</samp>
<h2>Caveats and improvements</h2>
<p>The process outlined above is simple enough that it can be automated: given a sixteen-step greyscale image, seek from the bottom left for a pixel in the desired palette row, replace the pixel and move forward. This, however, isn't ideal for steganographic purposes; the Brainfuck operators leave a unique signature in a bitmap of otherwise uniform numbers. There are two simple ways to increase the level of obfuscation:</p>
<ul>
 <li><strong>Colour</strong>: Instead of using a greyscale image, which offers easy colour matching, it's possible to use a coloured palette with any 8-bit image as the source. This involves replacing any existing instances of the operator characters with a close colour match, then further colour matching can be used to fill in the program, hiding the signal in an increased level of noise.</li>
 <li><strong>Compression</strong>: Noise levels can be increased further by compressing the image once it has been encoded, hiding any relation between the bitmap data and any Brainfuck program contained within. This increases the complexity of both the encoding and decoding algorithms, since a compression step must be employed around the transmission of the image, but it allows the images to be transmitted in a format that avoids suspicion.</li>
</ul>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Nov 2011.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Betel</title>
 <link href="https://imrannazar.com/scifi/betel" rel="alternate" type="text/html" title="Sci-fi Shorts: Betel" />
 <id>https://imrannazar.com/scifi/betel</id>
 <summary>Written on the theme of &quot;thirty&quot;. On the far edge of the galaxy, a planet where only thirty stars are visible notices that one of the thirty has disappeared. Flash sci-fi.</summary>
 <category term="Original Writings" />
 <published>Wed, 17 Aug 2011 19:06:20 +0000</published>
 <content type="text/html"><![CDATA[
   <p>There were never any more stars in the sky, or fewer. This far away from any other known solar system, there were only thirty stars visible up there, and every child grew up to know them well.
</p><p>
Cyrius, glowing a faint blue: the scientists said it was one of the brightest stars for a million light years, but out here it was a dull glow in the sky. Betel, a faraway red, constant in the sky since time immemorial. And the others, each one with a name known by all: even the alphabet had been adapted to thirty letters, one for each star in the sky.
</p><p>
Tonight was different. There were twenty nine stars: the letter B was missing. Betel had somehow gone out, its ruddy glow doused by the dark of space. Either something had happened to it, or the light was being... blocked in some way. The central astronomy agency soon found out that Betel wasn't missing; the latter suspicion was in fact true. A device of some sort was approaching from the rough direction of Betel, and only now was it close enough to block out the star's gaze upon us.
</p><p>
Morning came, and the strange entity was now visible as a blot against the iodine sky. Then it began to... expand, to unfurl, as though it were a net to cover the entire sky. Before too long, it had covered the sky in a grid of wire-thin lines. Then came a voice, deep and resonating: "SIMULATION ENDS IN TEN MINUTES."</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Printable Opcodes in x86 Real Mode</title>
 <link href="https://imrannazar.com/articles/x86-printable-opcodes" rel="alternate" type="text/html" title="Printable Opcodes in x86 Real Mode" />
 <id>https://imrannazar.com/articles/x86-printable-opcodes</id>
 <summary>Procedures for transmission of files over ASCII-text networks generally involve some form of encoding such as uuencode. When program executable files are being encoded for transmission, extra steps are required at the receiver before the program can be run. This article explores the concept of a program which has been encoded for an ASCII-text network, but can also be run directly without decoding; in this case, the article is limited to MS-DOS programs.</summary>
 <category term="Articles" />
 <published>Sat, 18 Jun 2011 21:30:30 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One of the major historical issues with the transmission of computer programs over the Internet has been how to avoid encoding problems: with FTP, for example, a file sent in text mode may have its newline characters translated by the FTP client into different values. For a program file, this would change the meaning of the code, and may result in failure when the downloaded file is executed.</p>
<p>The issue of transmision encoding is obviously a solved problem: FTP has a binary mode, which avoids text-based translation, while email has MIME-formatted attachments for the inclusion of files. Another way to approach the issue, however, is to produce executables which avoid the occurrence of the problem. Since a program, like any file, is nothing more than a stream of numbers, we can alleviate the transmission issue by producing programs which only use numbers that would be found in a text file; in the ASCII encoding standard, we can define these numbers as the "printable range", between 32 and 126.</p>
<p>Depending on the target CPU for the executable program, the limitation of only using the printable range will have different effects: for some processors, it is impossible to write a program under these constraints. In this article, I'll be looking at the combination of the x86 PC and MS-DOS, since this allows for a wide range of instructions to be used.</p>
<h2>Opcodes in the printable range</h2>
<p>Since the x86 base instruction set is derived from the 8080 CPU, a number of groups of instructions fall under the printable range, including conditional branches and arithmetic manipulation. The full list is as follows.</p>
<figure>
 <table class="opcodemap">
  <tr><th>20/&nbsp;</th><td><span title="Logical AND">AND</span> <em><span title="Register or location with register">r/m,r</span> (8-bit)</em></td><th>40/@</th><td><span title="Increment">INC</span> AX</td><th>60/`</th><td><span title="Push all general registers">PUSHA</span></td></tr>
  <tr><th>21/!</th><td><span title="Logical AND">AND</span> <em><span title="Register or location with register">r/m,r</span> (16-bit)</em></td><th>41/A</th><td><span title="Increment">INC</span> CX</td><th>61/a</th><td><span title="Pop all general registers">POPA</span></td></tr>
  <tr><th>22/"</th><td><span title="Logical AND">AND</span> <em><span title="Register with register or location">r,r/m</span> (8-bit)</em></td><th>42/B</th><td><span title="Increment">INC</span> DX</td><th>62/b</th><td><span title="Check memory bounds">BOUND</span> <em>r,m</em></td></tr>
  <tr><th>23/#</th><td><span title="Logical AND">AND</span> <em><span title="Register with register or location">r,r/m</span> (16-bit)</em></td><th>43/C</th><td><span title="Increment">INC</span> BX</td><th>63/c</th><td><span title="Adjust segment selector RPL">ARPL</span> <em><span title="Register or location with register">r/m,r</span> (16-bit)</em></td></tr>
  <tr><th>24/$</th><td><span title="Logical AND">AND</span> AL,imm</td><th>44/D</th><td><span title="Increment">INC</span> SP</td><th>64/d</th><td><span title="Segment override">FS:</span></td></tr>
  <tr><th>25/%</th><td><span title="Logical AND">AND</span> AX,imm</td><th>45/E</th><td><span title="Increment">INC</span> BP</td><th>65/e</th><td><span title="Segment override">GS:</span></td></tr>
  <tr><th>26/&amp;</th><td><span title="Segment override">ES:</span></td><th>46/F</th><td><span title="Increment">INC</span> SI</td><th>66/f</th><td><span title="Operand size override to 32-bit"><em>N/A</em></span></td></tr>
  <tr><th>27/'</th><td><span title="BCD adjust AL after addition">DAA</span></td><th>47/G</th><td><span title="Increment">INC</span> DI</td><th>67/g</th><td><span title="Address size override to 32-bit"><em>N/A</em></span></td></tr>
  <tr><th>28/(</th><td><span title="Subtract">SUB</span> <em><span title="Register from register or location">r/m,r</span> (8-bit)</em></td><th>48/H</th><td><span title="Decrement">DEC</span> AX</td><th>68/h</th><td><span title="Push">PUSH</span> imm16</td></tr>
  <tr><th>29/)</th><td><span title="Subtract">SUB</span> <em><span title="Register from register or location">r/m,r</span> (16-bit)</em></td><th>49/I</th><td><span title="Decrement">DEC</span> CX</td><th>69/i</th><td><span title="Integer multiply">IMUL</span> <em><span title="Register with register or location">r,r/m</span>,imm16</em></td></tr>
  <tr><th>2A/*</th><td><span title="Subtract">SUB</span> <em><span title="Register or location from register">r,r/m</span> (8-bit)</em></td><th>4A/J</th><td><span title="Decrement">DEC</span> DX</td><th>6A/j</th><td><span title="Push">Push</span> imm8</td></tr>
  <tr><th>2B/+</th><td><span title="Subtract">SUB</span> <em><span title="Register or location from register">r,r/m</span> (16-bit)</em></td><th>4B/K</th><td><span title="Decrement">DEC</span> BX</td><th>6B/k</th><td><span title="Integer multiply">IMUL</span> <em><span title="Register with register or location">r,r/m</span>,imm8</em></td></tr>
  <tr><th>2C/,</th><td><span title="Subtract">SUB</span> AL,imm8</td><th>4C/L</th><td><span title="Decrement">DEC</span> SP</td><th>6C/l</th><td><span title="Input byte from port">INSB</span></td></tr>
  <tr><th>2D/-</th><td><span title="Subtract">SUB</span> AX,imm16</td><th>4D/M</th><td><span title="Decrement">DEC</span> BP</td><th>6D/m</th><td><span title="Input word from port">INSW</span></td></tr>
  <tr><th>2E/.</th><td><span title="Segment override">CS:</span></td><th>4E/N</th><td><span title="Decrement">DEC</span> SI</td><th>6E/n</th><td><span title="Output byte to port">OUTSB</span></td></tr>
  <tr><th>2F//</th><td><span title="BCD adjust AL after subtraction">DAS</span></td><th>4F/O</th><td><span title="Decrement">DEC</span> DI</td><th>6F/o</th><td><span title="Output word to port">OUTSW</span></td></tr>
  <tr><th>30/0</th><td><span title="Exclusive OR">XOR</span> <em><span title="Register or location with register">r/m,r</span> (8-bit)</em></td><th>50/P</th><td><span title="Push">PUSH</span> AX</td><th>70/p</th><td><span title="Jump on overflow">JO</span> rel8</td></tr>
  <tr><th>31/1</th><td><span title="Exclusive OR">XOR</span> <em><span title="Register or location with register">r/m,r</span> (16-bit)</em></td><th>51/Q</th><td><span title="Push">PUSH</span> CX</td><th>71/q</th><td><span title="Jump if no overflow">JNO</span> rel8</td></tr>
  <tr><th>32/2</th><td><span title="Exclusive OR">XOR</span> <em><span title="Register with register or location">r,r/m</span> (8-bit)</em></td><th>52/R</th><td><span title="Push">PUSH</span> DX</td><th>72/r</th><td><span title="Jump on carry">JC</span> rel8</td></tr>
  <tr><th>33/3</th><td><span title="Exclusive OR">XOR</span> <em><span title="Register with register or location">r,r/m</span> (16-bit)</em></td><th>53/S</th><td><span title="Push">PUSH</span> BX</td><th>73/s</th><td><span title="Jump if no carry">JNC</span> rel8</td></tr>
  <tr><th>34/4</th><td><span title="Exclusive OR">XOR</span> AL,imm</td><th>54/T</th><td><span title="Push">PUSH</span> SP</td><th>74/t</th><td><span title="Jump if zero">JZ</span> rel8</td></tr>
  <tr><th>35/5</th><td><span title="Exclusive OR">XOR</span> AX,imm</td><th>55/U</th><td><span title="Push">PUSH</span> BP</td><th>75/u</th><td><span title="Jump if not zero">JNZ</span> rel8</td></tr>
  <tr><th>36/6</th><td><span title="Segment override">SS:</span></td><th>56/V</th><td><span title="Push">PUSH</span> SI</td><th>76/v</th><td><span title="Jump if below">JBE</span> rel8</td></tr>
  <tr><th>37/7</th><td><span title="ASCII adjust AL after addition">AAA</span></td><th>57/W</th><td><span title="Push">PUSH</span> DI</td><th>77/w</th><td><span title="Jump if not below">JNBE</span> rel8</td></tr>
  <tr><th>38/8</th><td><span title="Compare">CMP</span> <em><span title="Register from register or location">r/m,r</span> (8-bit)</em></td><th>58/X</th><td><span title="Pop">POP</span> AX</td><th>78/x</th><td><span title="Jump if sign">JS</span> rel8</td></tr>
  <tr><th>39/9</th><td><span title="Compare">CMP</span> <em><span title="Register from register or location">r/m,r</span> (16-bit)</em></td><th>59/Y</th><td><span title="Pop">POP</span> CX</td><th>79/y</th><td><span title="Jump if not sign">JNS</span> rel8</td></tr>
  <tr><th>3A/:</th><td><span title="Compare">CMP</span> <em><span title="Register or location from register">r,r/m</span> (8-bit)</em></td><th>5A/Z</th><td><span title="Pop">POP</span> DX</td><th>7A/z</th><td><span title="Jump if parity">JP</span> rel8</td></tr>
  <tr><th>3B/;</th><td><span title="Compare">CMP</span> <em><span title="Register or location from register">r,r/m</span> (16-bit)</em></td><th>5B/[</th><td><span title="Pop">POP</span> BX</td><th>7B/{</th><td><span title="Jump if not parity">JNP</span> rel8</td></tr>
  <tr><th>3C/&lt;</th><td><span title="Compare">CMP</span> AL,imm</td><th>5C/\</th><td><span title="Pop">POP</span> SP</td><th>7C/|</th><td><span title="Jump if less">JL</span> rel8</td></tr>
  <tr><th>3D/=</th><td><span title="Compare">CMP</span> AX,imm</td><th>5D/]</th><td><span title="Pop">POP</span> BP</td><th>7D/}</th><td><span title="Jump if not less">JNL</span> rel8</td></tr>
  <tr><th>3E/&gt;</th><td><span title="Segment override">DS:</span></td><th>5E/^</th><td><span title="Pop">POP</span> SI</td><th>7E/~</th><td><span title="Jump if less or equal">JLE</span> rel8</td></tr>
  <tr><th>3F/?</th><td><span title="ASCII adjust AL after subtraction">AAS</span></td><th>5F/_</th><td><span title="Pop">POP</span> DI</td></tr>
 </table>
 <figcaption>Table 1: Printable opcodes in the x86 instruction map</figcaption>
</figure>
<p>As can be seen in the above list, a good selection of opcodes is available in the x86 printable set; this allows three possible methods for producing programs using these operations:</p>
<ul>
 <li><strong>Programs from scratch</strong>: Using printable opcodes from the first stages of program production, to make applications that can be directly transmitted over a plain-text channel. This is obviously the most difficult option, and provides no consideration for transmission of existing programs; as such, it will not be looked at here.</li>
 <li><strong>External decoding</strong>: Programs are encoded in a plain-text representation, similar to Base64, and transmitted; a decoding application at the receiving end then processes the transmission into the original program. This solution is used by the <code>uuencode</code> utility, but is not an integrated solution.</li>
 <li><strong>Inline decoding</strong>: The program is encoded as with external decoding, but is provided alongside a decoding routine written with printable opcodes; this eliminates the need for an external decoder, and is the simplest solution: the program can simply be run as received, and will perform as expected.</li>
</ul>
<h2>Producing the encoding</h2>
<p>As mentioned above, the concept of Base64 can be applied in this case. Base64 encoding treats the program file as a long number, modulo 64: under this base, a number provided as a stream of bytes can be evenly divided into a stream of digits.</p>
<p>The canonical Base64 encoding is an adaptation of the concept behind hexadecimal: instead of using the standard denary digits in their normal position, the letters of the alphabet are used first. Values 0 to 25 are represented by the uppercase letters A-Z, 26 to 51 by the lowercase letters, and 52 to 61 by the digits 0-9. The remaining encodings 62 and 63 change between variations of the Base64 model, but are used as + and / in most variations.</p>
<p>This canonical encoding skips around the ASCII character set, which makes for complexity in the encoding and decoding algorithm. In the case of this article, the particular characters used for the encoding are unimportant as long as they are within the printable range: the algorithms are simplified if a contiguous range is used, so for simplicity a range from 32-95 will serve as the translation endpoint.</p>
<p>Encoding of the program for transmission can be performed by an external utility; the following C extract will produce a contiguous-base64 encoding of a source file.</p>
<samp>
 <h3>cb64-encode.c: Encoder to contiguous base64</h3>
 <pre><kbd>#include</kbd> <var>&lt;stdio.h&gt;</var>

<kbd>int</kbd> main(<kbd>int</kbd> argc, <kbd>char</kbd> **argv)
{
    <kbd>FILE</kbd> *in, *out;
    <kbd>int</kbd> fsize, i, n, o[<var>4</var>];

    <kbd>if</kbd>(argc != <var>2</var>)
    {
        printf(<var>"Usage: encode &lt;file&gt;\n"</var>);
        <kbd>return</kbd> <var>1</var>;
    }

    in = fopen(argv[<var>1</var>], <var>"rb"</var>);
    out = fopen(<var>"encode.out"</var>, <var>"wb"</var>);

    <s>/* Find out the size of the file */</s>
    fseek(in, <var>0</var>, <var>SEEK_END</var>); fsize = ftell(in); fseek(in, <var>0</var>, <var>SEEK_SET</var>);

    <kbd>for</kbd>(i=<var>0</var>; i&lt;fsize; i+=<var>3</var>)
    {
        <s>/* Retrieve 24 bits from the file */</s>
        n  = (fgetc(in) &lt;&lt; <var>0</var>);
        n |= (fgetc(in) &lt;&lt; <var>8</var>);
        n |= (fgetc(in) &lt;&lt; <var>16</var>);

        <s>/* Break out into four 6-bit values */</s>
        o[<var>0</var>] = ((n &gt;&gt; <var>18</var>) &amp; <var>63</var>) + <var>32</var>;
        o[<var>1</var>] = ((n &gt;&gt; <var>12</var>) &amp; <var>63</var>) + <var>32</var>;
        o[<var>2</var>] = ((n &gt;&gt;  <var>6</var>) &amp; <var>63</var>) + <var>32</var>;
        o[<var>3</var>] = ((n      ) &amp; <var>63</var>) + <var>32</var>;

        <s>/* Write encoded values */</s>
        fputc(o[<var>0</var>], out); fputc(o[<var>1</var>], out);
        fputc(o[<var>2</var>], out); fputc(o[<var>3</var>], out);
    }

    fclose(in);
    fclose(out);
    <kbd>return</kbd> <var>0</var>;
}</pre>
</samp>
<h2>The inline decoder</h2>
<p>With the source program encoded into the printable range, the remaining part of the process is the inline decoder. In theory, this is a simple reversal of the above code; the issue is complicated by the fact that the decoder must be written using printable opcodes only. In addition to using printable opcodes, some of the opcodes in the x86 instruction set use an optional <code>ModR/M</code> byte to specify their arguments: this additional byte defines the source and destination for the operation. A few examples:</p>
<samp>
 <h3>ModR/M samples</h3>
 <pre><kbd>XOR</kbd> AX,BX                     <s>; 33 C3</s>
<kbd>MOV</kbd> AL,<kbd>BYTE</kbd> [SI]              <s>; 8B 04</s>
<kbd>AND</kbd> CX,<kbd>WORD</kbd> [SI+<var>0293</var>]         <s>; 23 8C 93 02</s></pre>
</samp>
<p>As can be seen above, the <code>ModR/M</code> byte can take on any value, and each of the possible values encodes to a combination of source and destination. Of course, only some of these combinations encode to printable byte values: those selections are shown below.</p>
<figure>
 <table class="opcodemap">
  <tr><th rowspan="3"></th><th colspan="9">Destination</th></tr>
  <tr><th>8-bit</th><th>AL</th><th>CL</th><th>DL</th><th>BL</th><th>AH</th><th>CH</th><th>DH</th><th>BH</th></tr>
  <tr><th>16-bit</th><th>AX</th><th>CX</th><th>DX</th><th>BX</th><th>SP</th><th>BP</th><th>SI</th><th>DI</th></tr>
  <tr><th rowspan="16">Source</th><th>[BX+SI]</th><td></td><td></td><td></td><td></td><td>20</td><td>28</td><td>30</td><td>38</td></tr>
  <tr><th>[BX+DI]</th><td></td><td></td><td></td><td></td><td>21</td><td>29</td><td>31</td><td>39</td></tr>
  <tr><th>[BP+SI]</th><td></td><td></td><td></td><td></td><td>22</td><td>2A</td><td>32</td><td>3A</td></tr>
  <tr><th>[BP+DI]</th><td></td><td></td><td></td><td></td><td>23</td><td>2B</td><td>33</td><td>3B</td></tr>
  <tr><th>[SI]</th><td></td><td></td><td></td><td></td><td>24</td><td>2C</td><td>34</td><td>3C</td></tr>
  <tr><th>[DI]</th><td></td><td></td><td></td><td></td><td>25</td><td>2D</td><td>35</td><td>3D</td></tr>
  <tr><th>[addr]</th><td></td><td></td><td></td><td></td><td>26</td><td>2E</td><td>36</td><td>3E</td></tr>
  <tr><th>[BX]</th><td></td><td></td><td></td><td></td><td>27</td><td>2F</td><td>37</td><td>3F</td></tr>
  <tr><th>[BX+SI+disp]</th><td>40</td><td>48</td><td>50</td><td>58</td><td>60</td><td>68</td><td>70</td><td>78</td></tr>
  <tr><th>[BX+DI+disp]</th><td>41</td><td>49</td><td>51</td><td>59</td><td>61</td><td>69</td><td>71</td><td>79</td></tr>
  <tr><th>[BP+SI+disp]</th><td>42</td><td>4A</td><td>52</td><td>5A</td><td>62</td><td>6A</td><td>72</td><td>7A</td></tr>
  <tr><th>[BP+DI+disp]</th><td>43</td><td>4B</td><td>53</td><td>5B</td><td>63</td><td>6B</td><td>73</td><td>7B</td></tr>
  <tr><th>[SI+disp]</th><td>44</td><td>4C</td><td>54</td><td>5C</td><td>64</td><td>6C</td><td>74</td><td>7C</td></tr>
  <tr><th>[DI+disp]</th><td>45</td><td>4D</td><td>55</td><td>5D</td><td>65</td><td>6D</td><td>75</td><td>7D</td></tr>
  <tr><th>[BP+disp]</th><td>46</td><td>4E</td><td>56</td><td>5E</td><td>66</td><td>6E</td><td>76</td><td>7E</td></tr>
  <tr><th>[BX+disp]</th><td>47</td><td>4F</td><td>57</td><td>5F</td><td>67</td><td>6F</td><td>77</td><td></td></tr>
 </table>
 <figcaption>Table 2: Printable values for the ModR/M byte<br>addr is 16-bit, disp is 8-bit</figcaption>
</figure>
<p>Due to the limitations imposed by both the opcode range and the allowable addressing of ModR/M bytes, a few techniques have to be employed in code production:</p>
<ul>
 <li>
  <strong>Use of DOS initial values</strong>: When a program is loaded by MS-DOS or the Windows VDM, the registers have certain values at the start of execution. One of the important instances of this is that <code>AX</code> is zero. This value can be used throughout the program if it's saved to a register that's used solely for the purpose of providing zeroes. For example:
  <samp>
   <pre>; Use BX for zero register
<kbd>PUSH</kbd> AX
<kbd>POP</kbd> BX</pre>
  </samp>
 </li>
 <li>
  <strong>XOR masking</strong>: Since the <code>MOV</code> opcode is disallowed from use, and most immediate values cannot be represented as printable bytes, XOR can be used to clear unused bits. For example:
  <samp>
   <pre><s>; MOV AX, 0013h</s>
<kbd>PUSH</kbd> BX
<kbd>POP</kbd> AX
<kbd>XOR</kbd> AX, <var>2020h</var>
<kbd>XOR</kbd> AX, <var>2033h</var>

<s>; MOV AL, [SI+1Fh]</s>
<kbd>DEC</kbd> SI
<kbd>PUSH</kbd> BX
<kbd>POP</kbd> AX
<kbd>XOR</kbd> AX, [SI+<var>20h</var>]</pre>
  </samp>
 </li>
 <li><strong>Jump padding</strong>: Since jumps in the printable range are relative, forward jumps can only be made to destinations more than 31 bytes away. To facilitate this, extra bytes can be inserted if the destination isn't far enough away. This requires that the encoded output of the operations between the jump and its destination is known, since the code length is required to calculate the amount of padding required.</li>
 <li>
  <strong>Manual encoding</strong>: Some operations will not be intuitively selected by the assembler, and will be encoded into the non-printable range. To avoid this, the operation can be assembled by hand and inserted at the appropriate point. For the example of <code>XOR</code> where the source byte is 65 bytes from the opcode:
  <samp>
   <pre><s>; XOR AL, [SI+($-PRSTART)]</s>
<kbd>DB</kbd> <var>32h</var>, <var>44h</var>, <var>41h</var></pre>
  </samp>
 </li>
</ul>
<p>Using these techniques, it's possible to write the reverse decoder for the printable-opcode encoder detailed above, and attach the encoded program to it. The resultant program is shown below, in NASM assembly format.</p>
<samp>
 <h3>linenoise.com: Input program to be encoded</h3>
 <pre>    <kbd>mov</kbd> al, <var>0x13</var>
    <kbd>int</kbd> <var>0x10</var>               <s>; Set 320x200x8 graphics mode</s>
    <kbd>push</kbd> <var>0xA000</var>
    <kbd>pop</kbd> es                 <s>; Set destination segment</s>

lineloop:
    <kbd>mov</kbd> cx, <var>0x0140</var>         <s>; For 200 lines</s>
    <kbd>in</kbd> ax, <var>0x40</var>            <s>; Get a "random" number from the timer</s>
    <kbd>and</kbd> ax, <var>0xBF</var>
    <kbd>mul</kbd> cx
    <kbd>mov</kbd> di, ax             <s>; Write to that line on screen (mod 191)</s>
    <kbd>in</kbd> al, <var>0x40</var>            <s>; Get a "random" number</s>
    <kbd>rep</kbd> stosb              <s>; Write a line of that colour</s>

    <kbd>in</kbd> al, <var>0x60</var>            <s>; Check for a key</s>
    <kbd>dec</kbd> al
    <kbd>jnz</kbd> lineloop           <s>; Loop back if not ESC</s>

end:
    <kbd>ret</kbd>                    <s>; Return to DOS</s>
 </pre>
</samp>
<samp>
 <h3>linenoise-encoded.com: Encoded into printable opcodes</h3>
 <pre>    <kbd>pusha</kbd>               <s>; Save all registers for post-decoding</s>

    <s>; Initialise registers and zero-holder</s>
    <kbd>push</kbd> ax
    <kbd>push</kbd> ax
    <kbd>push</kbd> ax
    <kbd>push</kbd> ax
    <kbd>push</kbd> ax
    <kbd>pop</kbd> edx
    <kbd>pop</kbd> ebx
    <kbd>pop</kbd> cx

    <s>; Rewrite jpouter and jpinner</s>
    <kbd>xor</kbd> al, jpouter-<var>256</var>-<var>96</var>     <s>; Get a printable-range 8-bit value</s>
    <kbd>xor</kbd> ax, <var>0x235B</var>
    <kbd>xor</kbd> ax, <var>0x225B</var>             <s>; Add 256</s>
    <kbd>push</kbd> ax
    <kbd>pop</kbd> si                     <s>; Use this as the address</s>
    <kbd>push</kbd> bx
    <kbd>pop</kbd> ax
    <kbd>xor</kbd> al, <var>0x20</var>
    <kbd>sub</kbd> al, <var>0x55</var>               <s>; AL = 0xCB</s>
    <kbd>xor</kbd> [si+<var>0x60</var>], al          <s>; Opcode = 0xEB (JMP rel)</s>
    <kbd>xor</kbd> [si+<var>0x62</var>], al
    <kbd>xor</kbd> al,<var>0x34</var>                <s>; AL = 0xFF</s>
    <kbd>xor</kbd> [si+<var>0x61</var>], al          <s>; Set jump point to known value</s>
    <kbd>xor</kbd> [si+<var>0x63</var>], al

    <kbd>inc</kbd> ax                     <s>; AX = 0x0100</s>
    <kbd>push</kbd> ax
    <kbd>pop</kbd> bp                     <s>; BP = 0x0100</s>

    <s>; Set destination point (CS:1000 - 32)</s>
    <kbd>xor</kbd> ax,<var>0x3E30</var>
    <kbd>xor</kbd> ax,<var>0x3030</var>
    <kbd>sub</kbd> al,<var>32</var>
    <kbd>push</kbd> ax
    <kbd>pop</kbd> di

    <s>; Set source point (+256+8)</s>
    <kbd>push</kbd> bx
    <kbd>pop</kbd> ax
    <kbd>xor</kbd> ax,<var>0x3120</var>
    <kbd>xor</kbd> ax,<var>0x307E</var>
    <kbd>push</kbd> ax
    <kbd>pop</kbd> si

    <s>; Perform the decoding</s>
lpouter:
    <s>; In blocks of 4</s>
    <kbd>push</kbd> bx
    <kbd>push</kbd> bx
    <kbd>pop</kbd> eax
    <kbd>and</kbd> [di+<var>0x20</var>],eax
    <kbd>inc</kbd> cx
    <kbd>inc</kbd> cx
    <kbd>inc</kbd> cx
    <kbd>inc</kbd> cx

    <s>; Read 6 bits</s>
lpinner:
    <kbd>push</kbd> bx
    <kbd>pop</kbd> ax

    <kbd>db</kbd> <var>0x32</var>, <var>0x44</var>, <var>0x41</var>           <s>; xor al, [si+(source-$)]</s>
    <kbd>sub</kbd> al,<var>32</var>
    <kbd>cmp</kbd> al,<var>94</var>
    <kbd>je</kbd> end

    <s>; Push along by 6 bits, shift in the new bits</s>
    <kbd>imul</kbd> edx,[di+<var>0x20</var>],byte <var>64</var>

    <kbd>and</kbd> [di+<var>0x20</var>],ebx
    <kbd>xor</kbd> [di+<var>0x20</var>],edx          <s>; [Dest] = Shifted val</s>
    <kbd>xor</kbd> [di+<var>0x20</var>],al           <s>; [Dest] += next</s>
    <kbd>inc</kbd> si
    <kbd>dec</kbd> cx
    <kbd>jnz</kbd> jpinner

    <s>; Once the block of 4 is done, DI += 3</s>
    <kbd>inc</kbd> di
    <kbd>inc</kbd> di
    <kbd>inc</kbd> di
    <kbd>jnz</kbd> jpouter                <s>; Jump indirect</s>

    <s>; Jump padding, since the above code is 25 bytes long</s>
    <kbd>db</kbd> <var>'@@@@@@@'</var>

end:
    <kbd>push</kbd> bp
    <kbd>pop</kbd> ax                     <s>; AX = 0x0100</s>
    
    <s>; Rewrite jump to CS:1000</s>
    <kbd>xor</kbd> al,jpouter-<var>256</var>-<var>64</var>
    <kbd>push</kbd> ax
    <kbd>pop</kbd> si
    <kbd>push</kbd> bx
    <kbd>pop</kbd> ax
    <kbd>and</kbd> [si+<var>0x60</var>],ax
    <kbd>and</kbd> [si+<var>0x62</var>],ax           <s>; Clear opcode</s>
    <kbd>sub</kbd> al,<var>0x37</var>
    <kbd>xor</kbd> al,<var>0x20</var>                <s>; AL = 0xE9</s>
    <kbd>xor</kbd> [si+<var>0x60</var>],al           <s>; JMP (rel16)</s>
    <kbd>push</kbd> bx
    <kbd>pop</kbd> ax
    <kbd>xor</kbd> ax,<var>0x3E30</var>
    <kbd>xor</kbd> ax,<var>0x3072</var>              <s>; AX = 0x1000 - $</s>
    <kbd>xor</kbd> [si+<var>0x61</var>],ax
    <kbd>dec</kbd> di                     <s>; Clear Z flag</s>
    <kbd>popa</kbd>                       <s>; Retrieve all registers</s>
    <kbd>jnz</kbd> jpouter+<var>32</var>             <s>; Jump indirect to CS:1000</s>

    <s>; Rewritable jump points</s>
jpouter:
    <kbd>db</kbd> <var>0x20</var>
    <kbd>db</kbd> ($-lpouter)
jpinner:
    <kbd>db</kbd> <var>0x20</var>
    <kbd>db</kbd> ($-lpinner)

    <s>; The encoded program</s>
source:
    <kbd>db</kbd> <var>'S1.P &amp;@0N0&gt;@Y0% OR5 X?&lt; Y,&gt;)JO- _F#DZG7(___#'</var>
    <kbd>db</kbd> <var>126</var>                     <s>; EOF marker</s></pre>
</samp>
<p>The above encoded program runs in the same manner as the original, and produces the following output:</p>
<figure>
 <img src="/content/img/printable-opcodes-output.png" alt="Linenoise output">
 <figcaption>Figure 1: Output of linenoise-encoded.com</figcaption>
</figure>
<h2>Caveats and conclusion</h2>
<p>There are a few issues with this encoding mechanism. Firstly, it is heavily tied to MS-DOS .com programs, since the decoder is itself a DOS program and relies on the initial conditions provided by the MS-DOS program loader. Furthermore, it has a fixed destination for the decoded program of CS:1000h, which only allows programs of a little under 4 kilobytes to be used without modifying the decoder.</p>
<p>These issues, however, can be overlooked if the use of the encoding mechanism is kept to the domain of graphic demos and other simple programs which are to be written using printable opcodes. That domain may, of course, not be a large one.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jun 2011.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Edge Detection with Android Native Code</title>
 <link href="https://imrannazar.com/articles/android-ndk-edge-detection" rel="alternate" type="text/html" title="Edge Detection with Android Native Code" />
 <id>https://imrannazar.com/articles/android-ndk-edge-detection</id>
 <summary>Concluding an introduction to the development of augmented reality software, this part looks at implementing an edge detection algorithm overlaid on an Android smartphone&#039;s camera preview, and how the process can be optimised through use of the Android Native Development Kit.</summary>
 <category term="Articles" />
 <published>Sat, 21 May 2011 22:40:13 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>The source code to this project is now available in full, at: <a href="http://imrannazar.com/content/files/android-sobel.zip">http://imrannazar.com/content/files/android-sobel.zip</a></em></p>
<p>In the <a href="http://imrannazar.com/Augmented-Reality-with-the-Android-NDK:-Part-1">previous part</a> of this set of articles, I began an introduction to augmented reality, using the simple example of edge detection on Android smartphones; in that part, the camera hardware was introduced, and the framework of an application developed for the use of the camera preview. In this concluding part, the edge detection algorithm itself and its implementation will be explored.</p>
<h2>The Sobel operator</h2>
<p>The algorithm that will be used is the <a href="http://en.wikipedia.org/wiki/Sobel_operator">Sobel operator</a>, which works as a filter applied to each pixel in an image. The process iterates over each pixel in a row of the image, and over each row in turn, performing a factorised multiplication for each pixel value:</p>
<figure class="invertable">
 <img src="/content/img/android-sobel-example.png" alt="Matrix operation">
 <figcaption>Figure 1: Sobel operator formulation and example</figcaption>
</figure>
<samp>
 <pre>For Y = 1 to (Height-1)
    For X = 1 to (Width-1)
        Horiz_Sobel = (Input[Y-1][X-1] * -1) +
	              (Input[Y-1][X]   *  0) +
		      (Input[Y-1][X+1] *  1) +
		      (Input[Y]  [X-1] * -2) + 
		      (Input[Y]  [X]   *  0) +
		      (Input[Y]  [X+1] *  2) +
		      (Input[Y+1][X-1] * -1) +
		      (Input[Y+1][X]   *  0) +
		      (Input[Y+1][X+1] *  1)
        Vert_Sobel =  (Input[Y-1][X-1] * -1) +
	              (Input[Y-1][X]   * -2) +
		      (Input[Y-1][X+1] * -1) +
		      (Input[Y]  [X-1] *  0) + 
		      (Input[Y]  [X]   *  0) +
		      (Input[Y]  [X+1] *  0) +
		      (Input[Y+1][X-1] *  1) +
		      (Input[Y+1][X]   *  2) +
		      (Input[Y+1][X+1] *  1)
	Output[Y][X] = <a href="http://en.wikipedia.org/wiki/Pythagorean_addition">Pythag</a>(Horiz_Sobel, Vert_Sobel)
    Next X
Next Y</pre>
</samp>
<p>The calculation of the Sobel operator index can be simplified in two ways:</p>
<ul>
 <li><strong>Removal of multiplication</strong>: Some of the indices used by the algorithm are zero, which means that the associated terms are not used in the calculation at all; conversely, some indices are negative, which means a negative value must be added. Replacing multiplications with addition and subtraction of terms means that fewer operations are required to produce the value, making the calculation quicker.</li>
 <li><strong>Approximation of Pythagorean addition</strong>: For the purposes of this application, an exact value for the resultant Sobel value is not required, merely an approximation; a relatively close approximation of the Pythagorean operator is a simple average of the two values involved. This average will always be higher than the actual value, but will serve as a fair replacement.</li>
</ul>
<p>With these modifications, the calculation can be adapted to the following.</p>
<samp>
 <pre>For Y = 1 to (Height-1)
    For X = 1 to (Width-1)
        Horiz_Sobel = Input[Y+1][X+1] - Input[Y+1][X-1] + Input[Y][X+1] +
		      Input[Y][X+1] - Input[Y][X-1] - Input[Y][X-1] +
		      Input[Y-1][X+1] - Input[Y-1][X-1]
	Vert_Sobel = Input[Y+1][X+1] + Input[Y+1][X] + Input[Y+1][X]  +
		     Input[Y+1][X-1] - Input[Y-1][X+1] - Input[Y-1][X] -
		     Input[Y-1][X] - Input[Y-1][X-1]
	Output[Y][X] = Clamp((Horiz_Sobel + Vert_Sobel) / 2)
    Next X
Next Y</pre>
</samp>
<p>Before this filter can be applied to the camera preview image, the image must be taken from the camera and made ready for processing.</p>
<h2>Handling the Camera Preview</h2>
<p>As introduced in Part 1, the camera hardware is capable of automatically calling a predefined function whenever a frame of the preview is ready; this function is referred to as the "preview callback", and receives a <code>byte[]</code> containing the raw image data. By default, the preview image is in <code>NV21</code> format, a standard luminance/chrominance format; for the example of a 320x240 pixel NV21 image:</p>
<ul>
 <li>The first 76,800 bytes of the image are a direct luminance map, with each byte corresponding to a "brightness" or greyscale value for the corresponding pixel in the image;</li>
 <li>The following 38,400 bytes are a 2x2 subsampling of chrominance: for each 2x2-pixel block in the image, one byte encodes a U-chrominance, and the following byte a V-value.</li>
</ul>
<p>It's relatively straightforward to perform a Sobel calculation on the luminance part of the NV21 image, and a thresholded result can be placed into the overlay canvas for each output pixel:</p>
<samp>
 <h3>src/sobel/OverlayView.java: Sobel operation</h3>
 <pre>    <kbd>private int</kbd>[] mFrameSobel;

    <kbd>private void</kbd> setPreviewSize(Camera.Size s)
    {
	<s>// Allocate a 32-bit buffer as large as the preview</s>
	mFrameSobel = <kbd>new int</kbd>[s.width * s.height];
        mFrameSize = s;
    }

    <kbd>private void</kbd> setCamera(Camera c)
    {
        mCam = c;
	mCam.setPreviewCallback(<kbd>new</kbd> PreviewCallback()
	{
	    <s>// Called by camera hardware, with preview frame</s>
	    <kbd>public void</kbd> onPreviewFrame(<kbd>byte</kbd>[] frame, Camera c)
	    {
		Canvas cOver = mOverSH.lockCanvas(<var>null</var>);
		<kbd>try</kbd>
		{
		    <kbd>int</kbd> x, y;
		    <kbd>int</kbd> w = mFrameSize.width, pos;
		    <kbd>int</kbd> sobelX, sobelY, sobelFinal;
		    <kbd>for</kbd>(y=<var>1</var>; y&lt;(mFrameSize.height-<var>1</var>); y++)
		    {
		        pos = y * w + <var>1</var>;

		        <kbd>for</kbd>(x=<var>1</var>; x&lt;(mFrameSize.width-<var>1</var>); x++)
			{
			    sobelX = frame[pos+w+<var>1</var>] - frame[pos+w-<var>1</var>]
			           + frame[pos+<var>1</var>] + frame[pos+<var>1</var>]
				   - frame[pos-<var>1</var>] - frame[pos-<var>1</var>]
				   + frame[pos-w+<var>1</var>] - frame[pos-w-<var>1</var>];
			    sobelY = frame[pos+w+<var>1</var>] + frame[pos+w]
			           + frame[pos+w] + frame[pos+w-<var>1</var>]
				   - frame[pos-w+<var>1</var>] - frame[pos-w]
				   - frame[pos-w] - frame[pos-w-<var>1</var>];
			    sobelFinal = (sobelX + sobelY) / <var>2</var>;

			    <s>// Threshold at 48 (for example)</s>
			    <kbd>if</kbd>(sobelFinal &lt;  <var>48</var>)
			    	sobelFinal = <var>0</var>;
			    <kbd>if</kbd>(sobelFinal &gt;= <var>48</var>)
			    	sobelFinal = <var>255</var>;

			    <s>// Build a 32-bit RGBA value, either
			    // transparent black or opaque white</s>
			    mFrameSobel[pos] = (sobelFinal &lt;&lt; <var>0</var>) +
			                       (sobelFinal &lt;&lt; <var>8</var>) +
					       (sobelFinal &lt;&lt; <var>16</var>) +
					       (sobelFinal &lt;&lt; <var>24</var>);
			}
		    }


		    <s>// Copy calculated frame to bitmap, then
		    // translate onto overlay canvas</s>
		    Rect src = <kbd>new</kbd> Rect(<var>0</var>, <var>0</var>, mFrameSize.width, mFrameSize.height);
		    Rect dst = <kbd>new</kbd> Rect(<var>0</var>, <var>0</var>, cOver.getWidth(), cOver.getHeight());
		    Paint pt = <kbd>new</kbd> Paint();
		    Bitmap bmp = Bitmap.createBitmap(mFrameSobel,
		    				     mFrameSize.width,
		    				     mFrameSize.height,
						     Bitmap.Config.ARGB_8888);

		    pt.setColor(Color.WHITE);
		    pt.setAlpha(<var>0xFF</var>);
		    cOver.drawBitmap(bmp, src, dst, pt);
		}
		<kbd>catch</kbd>(<kbd>Exception</kbd> e)
		{
		    <s>// Log/trap rendering errors</s>
		}
		<kbd>finally</kbd>
		{
		    mOverSH.unlockCanvasAndPost(cOver);
		}
	    }
	});
    }</pre>
</samp>
<p>The above code, when run as part of the camera preview, yields the following view.</p>
<figure>
 <img src="/content/img/android-sobel-sample.jpg" alt="Sample output">
 <figcaption>Figure 2: Application output</figcaption>
</figure>
<h2>Optimising the operation</h2>
<p>As written, there's a problem with this application: speed. When run on a hardware device, the overlay calculation is incapable of maintaining a near-real-time speed of augmented display; in the case of my own hardware, a rendering speed of around 3 frames per second was achieved. This is due, in the main, to the calculations being performed within a buffer of managed memory in the Dalvik virtual machine: every access to the camera preview data is checked for boundary conditions, as is every pixel value written to the overlay canvas. All of these checks for boundary conditions take time away from the Sobel operation.</p>
<p>To alleviate this issue, the calculation can be performed in native code bypassing the virtual machine; this is done through the Android Native Development Kit (NDK). The NDK is an implementation of the Java Native Interface (JNI), and as such behaves in a very similar way to standard JNI: native code is placed into functions conforming to a particular naming standard, and they can then be called from the Java VM as specially marked <code>native</code> functions.</p>
<p>NDK native functions are named according to the package and class they're destined for: the standard format is <code>Java_&lt;package&gt;_&lt;class&gt;_&lt;function&gt;</code>. In this particular case, the destination is package <code>sobel</code> and class <code>OverlayView</code>, so the interface can be built as below.</p>
<samp>
 <h3>jni/native.c: NDK processing interface</h3>
 <pre><kbd>#include</kbd> <var>&lt;jni.h&gt;</var>

JNIEXPORT <kbd>void</kbd> JNICALL Java_sobel_OverlayView_nativeSobel(
	<s>/* Two parameters passed to every JNI function */</s>
	JNIEnv *env, jobject this,

	<s>/* Four parameters specific to this function */</s>
	jbyteArray frame, jint width, jint height, jobject out)
{
	<s>/* Perform Sobel operation, filling "out" */</s>
}</pre>
 <h3>src/sobel/OverlayView.java: Native function definition</h3>
 <pre><kbd>class</kbd> OverlayView
{
    <kbd>private native void</kbd> nativeSobel(<kbd>byte</kbd>[] frame,
    				    <kbd>int</kbd> width,
				    <kbd>int</kbd> height,
				    IntBuffer out);
}</pre>
</samp>
<p>Note that in the above code, the <code>int[]</code> array used beforehand for overlay output has been replaced by an <code>IntBuffer</code>; this is to allow access to the raw memory buffer for native work, since a standard <code>int[]</code> has memory allocated by the JVM, and cannot be written to by the JNI. <code>Buffer</code>s are designed to allow direct access to the buffer memory through the object's <code>GetDirectBufferAddress</code> function, which we can use for writing the output of the Sobel operation.</p>
<p>The Java code shown above for the operation can be translated directly to C code, as below:</p>
<samp>
 <h3>jni/native.c: Sobel implementation</h3>
 <pre><kbd>#include</kbd> <var>&lt;jni.h&gt;</var>

JNIEXPORT <kbd>void</kbd> JNICALL Java_sobel_OverlayView_nativeSobel(
	JNIEnv *env, jobject this,
	jbyteArray frame, jint width, jint height, jobject out)
{
	<s>/* Get a pointer to the raw output buffer */</s>
	jint *dest_buf = (jint*) ((*env)-&gt;GetDirectBufferAddress(env, out));

	<s>/* Get a pointer to (probably a copy of) the input */</s>
	jboolean frame_copy;
	jint *src_buf = (*env)-&gt;GetByteArrayElements(env, frame, &amp;frame_copy);

	<kbd>int</kbd> x, y, w = width, pos = width+<var>1</var>;
	<kbd>int</kbd> maxX = width-<var>1</var>, maxY = height-<var>1</var>;
	<kbd>int</kbd> sobelX, sobelY, sobelFinal;

	<kbd>for</kbd>(y=<var>1</var>; y&lt;maxY; y++, pos+=<var>2</var>)
	{
		<kbd>for</kbd>(x=<var>1</var>; x&lt;maxX; x++, pos++)
		{
			sobelX = src_buf[pos+w+<var>1</var>] - src_buf[pos+w-<var>1</var>]
			       + src_buf[pos+<var>1</var>] + src_buf[pos+<var>1</var>]
			       - src_buf[pos-<var>1</var>] - src_buf[pos-<var>1</var>]
			       + src_buf[pos-w+<var>1</var>] - src_buf[pos-w-<var>1</var>];
			sobelY = src_buf[pos+w+<var>1</var>] + src_buf[pos+w]
			       + src_buf[pos+w] + src_buf[pos+w-<var>1</var>]
			       - src_buf[pos-w+<var>1</var>] - src_buf[pos-w]
			       - src_buf[pos-w] - src_buf[pos-w-<var>1</var>];

			sobelFinal = (sobelX + sobelY) &gt;&gt; <var>1</var>;
			<kbd>if</kbd>(sobelFinal &lt; <var>48</var>)
				sobelFinal = <var>0</var>;
			<kbd>if</kbd>(sobelFinal &gt;= <var>48</var>)
				sobelFinal = <var>255</var>;

			dest_buf[pos] = (sobelFinal &lt;&lt; <var>0</var>)  |
					(sobelFinal &lt;&lt; <var>8</var>)  |
					(sobelFinal &lt;&lt; <var>16</var>) |
					(sobelFinal &lt;&lt; <var>24</var>);
		}
	}
}</pre>
 <h3>src/sobel/OverlayView.java: Calling the native function</h3>
 <pre>    <kbd>private</kbd> IntBuffer mFrameSobel;

    <kbd>private void</kbd> setPreviewSize(Camera.Size s)
    {
	<s>// Allocate a 32-bit direct buffer as large as the preview</s>
	mFrameSobel = ByteBuffer.allocateDirect(s.width * s.height * <var>4</var>)
				.asIntBuffer();
        mFrameSize = s;
    }

    <kbd>private void</kbd> setCamera(Camera c)
    {
        mCam = c;
	mCam.setPreviewCallback(<kbd>new</kbd> PreviewCallback()
	{
	    <s>// Called by camera hardware, with preview frame</s>
	    <kbd>public void</kbd> onPreviewFrame(<kbd>byte</kbd>[] frame, Camera c)
	    {
		Canvas cOver = mOverSH.lockCanvas(<var>null</var>);
		<kbd>try</kbd>
		{
		    nativeSobel(frame,
		    		mFrameSize.width, mFrameSize.width, 
				mFrameSobel);

		    <s>// Rewind the array after operation</s>
		    mFrameSobel.position(<var>0</var>);

		    Rect src = <kbd>new</kbd> Rect(<var>0</var>, <var>0</var>, mFrameSize.width, mFrameSize.height);
		    Rect dst = <kbd>new</kbd> Rect(<var>0</var>, <var>0</var>, cOver.getWidth(), cOver.getHeight());
		    Paint pt = <kbd>new</kbd> Paint();
		    Bitmap bmp = Bitmap.createBitmap(mFrameSobel,
		    				     mFrameSize.width,
		    				     mFrameSize.height,
						     Bitmap.Config.ARGB_8888);

		    pt.setColor(Color.WHITE);
		    pt.setAlpha(<var>0xFF</var>);
		    cOver.drawBitmap(bmp, src, dst, pt);
		}
		<kbd>catch</kbd>(<kbd>Exception</kbd> e)
		{
		    <s>// Log/trap rendering errors</s>
		}
		<kbd>finally</kbd>
		{
		    mOverSH.unlockCanvasAndPost(cOver);
		}
	    }
	});
    }</pre>
</samp>
<p>Once the Java code has been configured to call the native function for processing, the lack of extraneous work by the JVM results in a significant speed-up: under testing on my hardware, a speed of 15-20 frames per second was easily achievable, and this can be improved through further optimisation of the algorithm.</p>
<h2>In conclusion</h2>
<p>The Android documentation for the NDK states:<blockquote>"Using native code does not result in an automatic performance increase, but always increases application complexity."</blockquote></p>
<p>In the case of the memory-intensive processing presented here, the NDK has a significant advantage over the Java virtual machine, in that it doesn't perform bounds checking on array and pointer accesses. Since most augmented reality applications will need to work on the camera preview image, and provide an overlay on top of the preview, the technique of shunting processing into an NDK function can be useful.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, May 2011.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Camera Overlays with Android Native Code</title>
 <link href="https://imrannazar.com/articles/android-ndk-camera-overlays" rel="alternate" type="text/html" title="Camera Overlays with Android Native Code" />
 <id>https://imrannazar.com/articles/android-ndk-camera-overlays</id>
 <summary>One of the major current trends in smartphone applications is augmented reality: a view of reality with information laid on top. This can be as simple as a view of what the camera is currently seeing, with calculations based on position and direction. In the first of a two-part article series on Android development, this article looks at how to set up a camera view and access a canvas for the rendering of overlay information.</summary>
 <category term="Articles" />
 <published>Thu, 21 Apr 2011 19:07:47 +0000</published>
 <content type="text/html"><![CDATA[
   <p><em>The source code to this project is now available in full, at: <a href="http://imrannazar.com/content/files/android-sobel.zip">http://imrannazar.com/content/files/android-sobel.zip</a></em></p>
<p>One of the most demanding tasks for a smartphone application to take on is "augmented reality": producing a display of the world with information overlaid in real-time. This is generally done by using the smartphone's camera, in preview mode, to provide a base for a translucent overlay; the intensity of the task lies in calculating the contents of the overlay in a time-sensitive environment.</p>
<p>This article hopes to provide a gentle two-part introduction to augmented reality as implemented on Android-based smartphone devices. The process will be introduced using the example of an edge detector run on the camera's current view, and updated alongside the camera view in real-time. Many of the processes involved in producing such a view will apply to any software that seeks to provide a view based on the camera, so the code presented here will have wider application to programs of this class.</p>
<p>The edge detection algorithm that will be used in this article is the <a href="http://en.wikipedia.org/wiki/Sobel_operator">Sobel operator</a>; the algorithm will be covered in detail later, but the application developed here will, as a whole, be named after this operator. An example output for the application is shown below.</p>
<figure>
 <img src="/content/img/android-sobel-sample.jpg" alt="Sample output">
 <figcaption>Figure 1: Sample output</figure>
</figure>
<h2>Providing a camera view</h2>
<p>In order to overlay data on the camera preview screen, it's a prerequisite to be able to display the camera preview; this is done by rendering the preview onto a surface. For that to occur, the simplest method is to place a <code>SurfaceView</code>-type view on the application's main layout, and position it such that it covers the screen. This can be done through the standard layout XML:</p>
<samp>
 <h3>res/layout/main.xml: Main layout for camera preview</h3>
 <pre><s>&lt;?xml version="1.0" encoding="utf-8"?&gt;</s>
&lt;<kbd>FrameLayout</kbd> xmlns:android=<var>"http://schemas.android.com/apk/res/android"</var>
  android:orientation=<var>"vertical"</var>
  android:layout_width=<var>"fill_parent"</var>
  android:layout_height=<var>"fill_parent"</var>&gt;
    &lt;<kbd>SurfaceView</kbd> android:id=<var>"@+id/surface_camera"</var>
      android:layout_width=<var>"fill_parent"</var>
      android:layout_height=<var>"fill_parent"</var> /&gt;
&lt;<kbd>/FrameLayout</kbd>&gt;</pre>
</samp>
<p>With a <code>SurfaceView</code> made available, the application's main activity can place a surface and its associated canvas onto the view. To do this, the application needs to act as a <code>SurfaceHolder</code>, and implement the methods of a <code>SurfaceHolder.Callback</code>; this allows the Android operating system to treat the activity as an end-point for rendering surfaces. In code, it's a simple process to define an activity as a surface holder callback: three methods are made available by the <code>SurfaceHolder.Callback</code> interface.</p>
<samp>
 <h3>src/sobel/Sobel.java: Main activity</h3>
 <pre><kbd>package</kbd> sobel;
<kbd>public class</kbd> Sobel <kbd>extends</kbd> Activity <kbd>implements</kbd> SurfaceHolder.Callback
{
    <s>/* Activity event handlers */</s>
    <s>// Called when activity is initialised by OS</s>
    @Override
    <kbd>public void</kbd>onCreate(Bundle inst)
    {
    	<kbd>super</kbd>.onCreate(inst);
	setContentView(R.layout.main);

	<s>// Initialise camera</s>
	initCamera();
    }

    <s>// Called when activity is closed by OS</s>
    @Override
    <kbd>public void</kbd> onDestroy()
    {
        <s>// Turn off the camera</s>
	stopCamera();
    }

    <s>/* SurfaceHolder event handlers */</s>
    <s>// Called when the surface is first created</s>
    <kbd>public void</kbd> surfaceCreated(SurfaceHolder sh)
    {
        <s>// No action required</s>
    }

    <s>// Called when surface dimensions etc change</s>
    <kbd>public void</kbd> surfaceChanged(SurfaceHolder sh,
                               <kbd>int</kbd> format,
			       <kbd>int</kbd> width,
			       <kbd>int</kbd> height)
    {
        <s>// Start camera preview</s>
	startCamera(sh, width, height);
    }

    <s>// Called when the surface is closed/destroyed</s>
    <kbd>public void</kbd> surfaceDestroyed(SurfaceHolder sh)
    {
        <s>// No action required</s>
    }
}</pre>
</samp>
<p>The above code will deal with the initialisation of the application and its surface, but the camera hardware needs to be initialised and setup for the preview to be available. This is done in three steps:
<ol>
 <li><strong>Open</strong> the camera, when the application is initialised;</li>
 <li><strong>Set parameters</strong> for the camera, including the width and height of the preview;</li>
 <li><strong>Start preview</strong> and set surface for the preview output.</li>
</ol></p>
<p>The camera helper functions mentioned in the above code sample can be filled in to perform these steps:</p>
<samp>
 <h3>src/sobel/Sobel.java: Camera initialisation</h3>
 <pre>    <kbd>private</kbd> Camera mCam;
    <kbd>private</kbd> SurfaceView mCamSV;
    <kbd>private</kbd> SurfaceHolder mCamSH;

    <s>// Initialise camera and surface</s>
    <kbd>private void</kbd> initCamera()
    {
    	mCamSV = (SurfaceView)findViewById(R.id.surface_camera);
	mCamSH = mCamSV.getHolder();
	mCamSH.addCallback(<kbd>this</kbd>);

	mCam = Camera.open();
    }

    <s>// Setup camera based on surface parameters</s>
    <kbd>private void</kbd> startCamera(SurfaceHolder sh, <kbd>int</kbd> width, <kbd>int</kbd> height)
    {
    	Camera.Parameters p = mCam.getParameters();
	p.setPreviewSize(width, height);

	mCam.setParameters(p);

	<kbd>try</kbd>
	{
	    mCam.setPreviewDisplay(sh);
	}
	<kbd>catch</kbd>(<kbd>Exception</kbd> e)
	{
	    <s>// Log surface setting exceptions</s>
	}

	mCam.startPreview();
    }

    <s>// Stop camera when application ends</s>
    <kbd>private void</kbd> stopCamera()
    {
        mCamSH.removeCallback(<kbd>this</kbd>);

    	mCam.stopPreview();
	mCam.release();
    }</pre>
</samp>
<p>One consideration to make when setting up the camera is that the size of the surface prepared for preview may not be a size supported by the camera subsystem. If this is the case, and the activity attempts to set a preview size based on the surface size, the application may force-close when it starts. A work-around for this is not to use the surface's dimensions when setting a preview size, but instead to ask the camera which preview sizes are supported, and to use one of those. The list of preview sizes can be retrieved through the camera's <code>Parameters</code> object:</p>
<samp>
 <h3>src/sobel/Sobel.java: Using supported preview sizes</h3>
 <pre>    <kbd>private void</kbd> startCamera(SurfaceHolder sh, <kbd>int</kbd> width, <kbd>int</kbd> height)
    {
    	Camera.Parameters p = mCam.getParameters();
	<kbd>for</kbd>(Camera.Size s : p.getSupportedPreviewSizes())
	{
	    <s>// In this instance, simply use the first available
	    // preview size; could be refined to find the closest
	    // values to the surface size</s>
	    p.setPreviewSize(s.width, s.height);
	    <kbd>break</kbd>;
	}

	mCam.setParameters(p);

	<kbd>try</kbd>
	{
	    mCam.setPreviewDisplay(sh);
	}
	<kbd>catch</kbd>(<kbd>Exception</kbd> e)
	{
	    <s>// Log surface setting exceptions</s>
	}

	mCam.startPreview();
    }</pre>
</samp>
<p>The application is now equipped to produce a preview of the camera's current field of view. The preview may appear alongside an application title bar, notification area and so forth; to remove these and gain an unobstructed rendering of the preview, the application can request to be made fullscreen:</p>
<samp>
 <h3>src/sobel/Sobel.java: Fullscreen activity</h3>
 <pre>    @Override
    <kbd>public void</kbd> onCreate(Bundle inst)
    {
    	<kbd>super</kbd>.onCreate(inst);

	getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
	                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
	setContentView(R.layout.main);
	initCamera();
    }</pre>
</samp>
<h2>Providing an overlay</h2>
<p>Now that the camera preview is being rendered into a <code>SurfaceView</code>, the next step in augmented reality is the ability to draw pixels and/or shapes over the preview image. Since the camera hardware is directly drawing to the surface made available to it, this surface cannot be used for additional drawing: any output made to the surface will be automatically overwritten by the camera.</p>
<p>This problem can be resolved by providing an additional surface, positioned over the top of the camera preview, onto which things can be drawn by the application. The new surface can also be a <code>SurfaceView</code>, but if the base Android view is utilised in this instance, it cannot be used to draw dynamic content: the <code>SurfaceView</code> must be extended into a new class. For the purposes of this application, the class can be referred to as <code>OverlayView</code>:</p>
<samp>
 <h3>src/sobel/OverlayView.java: Class definition</h3>
 <pre><kbd>package</kbd> sobel;
<kbd>public class</kbd> OverlayView <kbd>extends</kbd> SurfaceView
{
    <kbd>private</kbd> SurfaceHolder mOverSH;

    <kbd>public void</kbd> OverlayView(Context ctx, AttributeSet attr)
    {
    	<kbd>sup</kbd>er(ctx, attr);

	mOverSH = getHolder();
    }
}</pre>
 <h3>src/sobel/Sobel.java: Initialising the OverlayView</h3>
 <pre>    <kbd>private</kbd> OverlayView mOverSV;
 
    <kbd>private void</kbd> initCamera()
    {
    	mCamSV = (SurfaceView)findViewById(R.id.surface_camera);
	mCamSH = mCamSV.getHolder();
	mCamSH.addCallback(<kbd>this</kbd>);

	mCam = Camera.open();

	mOverSV = (OverlayView)findViewById(R.id.surface_overlay);
	mOverSV.getHolder().setFormat(PixelFormat.TRANSLUCENT);
	mOverSV.setCamera(mCam);
    }

    <kbd>private void</kbd> startCamera(SurfaceHolder sh, <kbd>int</kbd> width, <kbd>int</kbd> height)
    {
    	Camera.Parameters p = mCam.getParameters();
	<kbd>for</kbd>(Camera.Size s : p.getSupportedPreviewSizes())
	{
	    p.setPreviewSize(s.width, s.height);
	    mOverSV.setPreviewSize(s);
	    <kbd>break</kbd>;
	}
	<s>// ...</s>
    }</pre>
</samp>
<p>In order to lay this new view class over the camera's preview surface, the layout XML needs to be modified to load in the overlay view beforehand:</p>
<samp>
 <h3>res/layout/main.xml: Main layout for overlaid preview</h3>
 <pre><s>&lt;?xml version="1.0" encoding="utf-8"?&gt;</s>
&lt;<kbd>FrameLayout</kbd> xmlns:android=<var>"http://schemas.android.com/apk/res/android"</var>
  android:orientation=<var>"vertical"</var>
  android:layout_width=<var>"fill_parent"</var>
  android:layout_height=<var>"fill_parent"</var>&gt;
    &lt;sobel.OverlayView android:id=<var>"@+id/surface_overlay"</var>
      android:layout_width=<var>"fill_parent"</var>
      android:layout_height=<var>"fill_parent"</var> /&gt;
    &lt;<kbd>SurfaceView</kbd> android:id=<var>"@+id/surface_camera"</var>
      android:layout_width=<var>"fill_parent"</var>
      android:layout_height=<var>"fill_parent"</var> /&gt;
&lt;<kbd>/FrameLayout</kbd>&gt;</pre>
</samp>
<p>With an overlay in place, the content on the overlay needs to be drawn, and regularly updated. Drawing onto a surface is a familiar concept from computer graphics, requiring the locking of a canvas and the drawing of primitives to the canvas; keeping the canvas regularly updated against the camera preview is a little less familiar. A regular update can be achieved in one of two ways:</p>
<p><ul>
 <li><strong>Timing</strong>: A method of the OverlayView is called every few milliseconds, which fetches the current camera preview from its rendered surface. This is a theoretically sound concept, but the camera hardware keeps the preview surface permanently locked, so the application is unable to gain access to it.</li>
 <li><strong>Callback</strong>: A method of the OverlayView is defined as a "preview callback", and is called automatically by the camera hardware whenever a preview is rendered. The innate advantage to this method is that the camera provides a <code>byte[]</code> of the contents of the camera preview, which can easily be used for calculation of an overlay.</li>
</ul></p>
<p>To set up a callback to a method in the OverlayView, the view must first know about the camera: a handle to the camera must be passed over from the main activity. In addition, it's useful for the OverlayView to know the size of preview image it's working with, since the callback method doesn't provide dimensions. The calls to these methods can be seen in the above code sample from <code>Sobel.java</code>, made at initialisation time; the methods are outlined below.</p>
<samp>
 <h3>src/sobel/OverlayView.java: Setting up a callback</h3>
 <pre>    <kbd>private</kbd> Camera mCam;
    <kbd>private</kbd> Camera.Size mFrameSize;

    <s>// Called by Sobel.surfaceChanged, to set dimensions</s>
    <kbd>private void</kbd> setPreviewSize(Camera.Size s)
    {
        mFrameSize = s;
	mFrameCount = 0;
    }

    <s>// Called by Sobel.initCamera, to set callback</s>
    <kbd>private void</kbd> setCamera(Camera c)
    {
        mCam = c;
	mCam.setPreviewCallback(<kbd>new</kbd> PreviewCallback()
	{
            <kbd>private int</kbd> mFrameCount;

	    <s>// Called by camera hardware, with preview frame</s>
	    <kbd>public void</kbd> onPreviewFrame(<kbd>byte</kbd>[] frame, Camera c)
	    {
		Canvas cOver = mOverSH.lockCanvas(<var>null</var>);
		<kbd>try</kbd>
		{
	            <s>// Perform overlay rendering here
		    // Here, draw an incrementing number onscreen</s>
		    Paint pt = new Paint();
		    pt.setColor(Color.WHITE);
		    pt.setTextSize(<var>16</var>);
		    cOver.drawText(<kbd>Integer</kbd>.toString(mFrameCount++),
		                   <var>10</var>, <var>10</var>, pt);
		}
		<kbd>catch</kbd>(<kbd>Exception</kbd> e)
		{
		    <s>// Log/trap rendering errors</s>
		}
		<kbd>finally</kbd>
		{
		    mOverSH.unlockCanvasAndPost(cOver);
		}
	    }
	});
    }</pre>
</samp>
<p>Running the above code on hardware results in something akin to the following image:</p>
<figure>
 <img src="/content/img/android-sobel-canvas.jpg" alt="Canvas example">
 <figcaption>Figure 2: Overlay canvas rendering</figcaption>
</figure>
<h2>In Part 2: Edge detection</h2>
<p>The above code takes the application to a point where it can retrieve data from the camera preview (through the preview frame callback's <code>byte</code>[] parameter), and render an overlay. In the second part of this article, I'll look at how the preview data can be run through the Sobel edge detection filter, and how the result can be displayed on the overlay.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Apr 2011.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Timers</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/timers" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Timers" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/timers</id>
 <summary>Like most computer and console systems, the GameBoy offers a hardware timer for use by games, if they wish to keep time more accurately than at the rate of vertical blanking refresh. In addition to a controllable timer, the GameBoy provides a facility for directly examining a fixed divisor of the system clock; in this article, both aspects of the timer are investigated, and the use of the timer for generating random numbers is also looked at, using the example of Tetris.</summary>
 <category term="Series" />
 <published>Fri, 25 Feb 2011 00:43:38 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 10 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>Since the first computers were put together, one of their basic functions has been to keep time: to coordinate actions according to timers. Even the simplest of games has an element of time to it: Pong, for example, needs to move the ball across the screen at a particular rate. In order to handle these timing issues, every games console has some form of timer to allow for things to happen at a given moment, or at a specific rate.</p>
<p>The GameBoy is no exception to this rule, and contains a set of registers which automatically increment based on a programmable schedule. In this part of the series, I'll be investigating the structure and operation of the timer, and how it can be used to seed pseudo-random number generators, such as the one contained in Tetris and its various clones. One example of a Tetris clone which uses the timer, to pick random pieces for the game, is demonstrated below.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-timer.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with timer</figcaption>
</figure>
<h2>Timer structure</h2>
<p>The GameBoy's CPU, as described in the <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-The-CPU">first part</a> of this series, runs on a 4,194,304Hz clock, with two internal measures of the time taken to execute each instruction: the T-clock, which increments with each clock step, and the M-clock, which increments at a quarter of the speed (1,048,576Hz). These clocks are used as the source of the timer, which counts up, in turn, at a quarter of the rate of the M-clock: 262,144Hz. In this article, I'll refer to this final value as the timer's "base speed".</p>
<p>The GameBoy's timer hardware offers two separate timer registers: the system works by incrementing the value in each of these registers at a pre-determined rate. The "divider" timer is permanently set to increment at 16384Hz, one sixteenth of the base speed; since it's only an eight-bit register, its value will go back to zero after it reaches 255. The "counter" timer is more programmable: it can be set to one of four speeds (the base divided by 1, 4, 16 or 64), and it can be set to go back to a value that isn't zero when it overflows past 255. In addition, the timer hardware will send an interrupt to the CPU, as described in <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Interrupts">part 8</a>, whenever the "counter" timer does overflow.</p>
<p>There are four registers used by the timer; these are made available for use by the system as part of the I/O page, just like the graphics and interrupt registers:</p>
<figure>
 <table>
  <tr><th>Address</th><th>Register</th><th>Details</th></tr>
  <tr><td>0xFF04</td><td>Divider</td><td>Counts up at a fixed 16384Hz;<br>reset to 0 whenever written to</td></tr>
  <tr><td>0xFF05</td><td>Counter</td><td>Counts up at the specified rate<br>Triggers INT 0x50 when going 255-&gt;0</td></tr>
  <tr><td>0xFF06</td><td>Modulo</td><td>When Counter overflows to 0,<br>it's reset to start at Modulo</td><tr>
  <tr><td>0xFF07</td><td>Control</td><td>
   <table>
    <tr><th>Bits</th><th>Function</th><th>Details</th></tr>
    <tr><td>0-1</td><td>Speed</td><td>00:   4096Hz<br>01: 262144Hz<br>10:  65536Hz<br>11:  16384Hz</td></tr>
    <tr><td>2</td><td>Running</td><td>1 to run timer, 0 to stop</td></tr>
    <tr><td>3-7</td><td colspan="2">Unused</td></tr>
   </table>
  </td></tr>
 </table>
 <figcaption>Table 1: Timer registers</figcaption>
</figure>
<p>Since the "counter" timer triggers an interrupt when it overflows, it can be especially useful if a game requires something to happen at a regular interval. However, a Gameboy game can generally use the <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Interrupts">vertical blank</a> to much the same effect, since it occurs at a regular pace of almost 60Hz; the vertical blanking handler can be used not only to refresh the screen contents, but to check the keypad and update the game state. Therefore, there's little call for use of the timer in traditional Gameboy games, though it can be used to greater effect in graphic demos.</p>
<h2>Implementing the timer emulation</h2>
<p>The emulation developed in this article series uses the CPU's clock as the basic unit of time. For that reason, it's simplest to maintain a clock for the timer that runs in step with the CPU clock, and is updated by the dispatch function. It's convenient at this stage to keep the DIV register as a separate entity to the controllable timer, incremented at 1/16th the rate again of the fastest timer step:</p>
<samp>
 <h3>Timer.js: Clock increment</h3>
 <pre>TIMER = {
    _clock: {
        main: <var>0</var>,
	sub:  <var>0</var>,
	div:  <var>0</var>
    },

    _reg: {
        div:  <var>0</var>,
	tima: <var>0</var>,
	tma:  <var>0</var>,
	tac:  <var>0</var>
    },

    inc: <kbd>function</kbd>()
    {
        <s>// Increment by the last opcode's time</s>
        TIMER._clock.sub += Z80._r.m;

	<s>// No opcode takes longer than 4 M-times,
	// so we need only check for overflow once</s>
	<kbd>if</kbd>(TIMER._clock.sub &gt;= <var>4</var>)
	{
	    TIMER._clock.main++;
	    TIMER._clock.sub -= <var>4</var>;

	    <s>// The DIV register increments at 1/16th
	    // the rate, so keep a count of this</s>
	    TIMER._clock.div++;
	    <kbd>if</kbd>(TIMER._clock.div == <var>16</var>)
	    {
	        TIMER._reg.div = (TIMER._reg.div+<var>1</var>) &amp; <var>255</var>;
		TIMER._clock.div = <var>0</var>;
	    }
	}

	<s>// Check whether a step needs to be made in the timer</s>
	TIMER.check();
    }
};</pre>
 <h3>Z80.js: Dispatcher</h3>
 <pre><kbd>while</kbd>(<var>true</var>)
{
    <s>// Run execute for this instruction</s>
    <kbd>var</kbd> op = MMU.rc(Z80._r.pc++);
    Z80._map[op]();
    Z80._r.pc &amp;= <var>65535</var>;
    Z80._clock.m += Z80._r.m;
    Z80._clock.t += Z80._r.t;

    <s>// Update the timer</s>
    TIMER.inc();

    Z80._r.m = <var>0</var>;
    Z80._r.t = <var>0</var>;

    <s>// If IME is on, and some interrupts are enabled in IE, and
    // an interrupt flag is set, handle the interrupt</s>
    <kbd>if</kbd>(Z80._r.ime &amp;&amp; MMU._ie &amp;&amp; MMU._if)
    {
        <s>// Mask off ints that aren't enabled</s>
        <kbd>var</kbd> ifired = MMU._ie &amp; MMU._if;

	<kbd>if</kbd>(ifired &amp; <var>0x01</var>)
	{
	    MMU._if &amp;= (<var>255</var> - <var>0x01</var>);
	    Z80._ops.RST40();
	}
    }

    Z80._clock.m += Z80._r.m;
    Z80._clock.t += Z80._r.t;

    <s>// Update timer again, in case a RST occurred</s>
    TIMER.inc();
}</pre>
</samp>
<p>From here, the controllable timer is made up of varying divisions of the base speed, making it relatively simple to check whether the timer values need to be stepped up, and to provide the registers as part of the memory I/O page. The interface between the following section of code and the MMU I/O page handler, is left as an exercise for the reader.</p>
<samp>
 <h3>Timer.js: Register check and update</h3>
 <pre>    check: <kbd>function</kbd>()
    {
        <kbd>if</kbd>(TIMER._reg.tac &amp; <var>4</var>)
	{
	    <kbd>switch</kbd>(TIMER._reg.tac &amp; <var>3</var>)
	    {
	        <kbd>case</kbd> <var>0</var>: threshold = <var>64</var>; <kbd>break</kbd>;		<s>// 4K</s>
		<kbd>case</kbd> <var>1</var>: threshold = <var> 1</var>; <kbd>break</kbd>;		<s>// 256K</s>
		<kbd>case</kbd> <var>2</var>: threshold = <var> 4</var>; <kbd>break</kbd>;		<s>// 64K</s>
		<kbd>case</kbd> <var>3</var>: threshold = <var>16</var>; <kbd>break</kbd>;		<s>// 16K</s>
	    }

	    <kbd>if</kbd>(TIMER._clock.main &gt;= threshold) TIMER.step();
	}
    },

    step: <kbd>function</kbd>()
    {
        <s>// Step the timer up by one</s>
	TIMER._clock.main = <var>0</var>;
    	TIMER._reg.tima++;

	<kbd>if</kbd>(TIMER._reg.tima &gt; <var>255</var>)
	{
	    <s>// At overflow, refill with the Modulo</s>
	    TIMER._reg.tima = TIMER._reg.tma;

	    <s>// Flag a timer interrupt to the dispatcher</s>
	    MMU._if |= <var>4</var>;
	}
    },

    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr)
	{
	    <kbd>case</kbd> <var>0xFF04</var>: <kbd>return</kbd> TIMER._reg.div;
	    <kbd>case</kbd> <var>0xFF05</var>: <kbd>return</kbd> TIMER._reg.tima;
	    <kbd>case</kbd> <var>0xFF06</var>: <kbd>return</kbd> TIMER._reg.tma;
	    <kbd>case</kbd> <var>0xFF07</var>: <kbd>return</kbd> TIMER._reg.tac;
	}
    },

    wb: <kbd>function</kbd>(addr, val)
    {
	<kbd>switch</kbd>(addr)
	{
	    <kbd>case</kbd> <var>0xFF04</var>: TIMER._reg.div = <var>0</var>; <kbd>break</kbd>;
	    <kbd>case</kbd> <var>0xFF05</var>: TIMER._reg.tima = val; <kbd>break</kbd>;
	    <kbd>case</kbd> <var>0xFF06</var>: TIMER._reg.tma = val; <kbd>break</kbd>;
	    <kbd>case</kbd> <var>0xFF07</var>: TIMER._reg.tac = val &amp; <var>7</var>; <kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Seeding a pseudo-random number generator</h2>
<p>A major component of many games is unpredictability: Tetris, for instance, will throw an unknown pattern of pieces down the well, and the game consists of building rows using these pieces. Ideally, a computer provides unpredictability by generating random numbers, but this runs contrary to the methodical nature of a computer; it's not possible for a computer to provide a truly random pattern of numbers. Various algorithms exist to produce sequences of numbers that look superficially like they're random, and these are called <em>pseudo</em>-random number generation (PRNG) algorithms.</p>
<p>A PRNG is generally implemented as a formula that, given a particular input number, will produce another number with almost no relation to the input. For Tetris, nothing so complicated is required; instead, the following code is used to produce a seemingly random block.</p>
<samp>
 <h3>Tetris.asm: Select new block</h3>
 <pre>BLK_NEXT = <var>0xC203</var>
BLK_CURR = <var>0xC213</var>
REG_DIV  = <var>0x04</var>

NBLOCK: ld hl, BLK_CURR		<s>; Bring the next block</s>
	ld a, (BLK_NEXT)	<s>; forward to current</s>
	ld (hl),a
	and <var>0xFC</var>		<s>; Clear out any rotations</s>
	ld c,a			<s>; and hold onto previous</s>

	ld h,<var>3</var>			<s>; Try the following 3 times</s>

.seed:	ldh a, (REG_DIV)	<s>; Get a "random" seed</s>
	ld b,a
.loop:	xor a			<s>; Step down in sevens</s>
.seven:	dec b			<s>; until zero is reached</s>
	jr z, .next		<s>; This loop is equivalent</s>
	inc a			<s>; to (a%7)*4</s>
	inc a
	inc a
	inc a
	cp <var>28</var>
	jr z, .loop
	jr .seven

.next:	ld e,a			<s>; Copy the new value</s>
	dec h			<s>; If this is the</s>
	jr z, .end		<s>; last try, just use this</s>
	or c			<s>; Otherwise check</s>
	and <var>0xFC</var>		<s>; against the previous block</s>
	cp c			<s>; If it's the same again,</s>
	jr z, .seed		<s>; try another random number</s>
.end:	ld a,e			<s>; Get the copy back</s>
	ld (BLK_NEXT), a	<s>; This is our next block</s></pre>
</samp>
<p>The basis of the Tetris block selector is the DIV register: since the selection routine is only run once every few seconds, the register will have an unknown value on any given run, and it thus makes a fair approximation of a random number source. With the timer system having been emulated, Tetris and its clones can be emulated to full functionality, as shown in Figure 1.</p>
<h2>Coming up: Sound</h2>
<p>One aspect of game emulation which has been overlooked until now is the generation of sound, and the synchronisation of sound to the speed of the emulation. Over and above the aspect of sound generation by the emulator, is the method by which sound is output to the browser; the next part of this series will investigate the issues surrounding sound output mechanisms, and whether a coherent strategy can be put together for sound production in JavaScript.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Feb 2011.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: The Harness</title>
 <link href="https://imrannazar.com/scifi/the-harness" rel="alternate" type="text/html" title="Sci-fi Shorts: The Harness" />
 <id>https://imrannazar.com/scifi/the-harness</id>
 <summary>The tide of an interplanetary war is turned when a rogue black hole enters the solar system, and is captured by Earth forces. First published in &lt;a href=&quot;http://www.amazon.co.uk/dp/B004LLIGOQ&quot;&gt;IFWG Story Quest magazine&lt;/a&gt;, hard sci-fi.</summary>
 <category term="Original Writings" />
 <published>Wed, 02 Feb 2011 09:55:13 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The war had almost drained our combined resources of energy: even though
we were closer to the Sun, the solar power simply couldn't be collected
without materials to build solar collectors. With every last scrap of metal
engaged in the war effort, or otherwise up in space somewhere, it was
impossible to get anything done on the surface.
</p><p>
The black hole changed that. It was spotted a few years ago, slowly drifting
across the plane of the solar system; it was only seen at all because it
crossed the path of Venus, and the planet changed shape for a few hours. In
their haste to focus attacks on Earth, the invaders missed the shift in the
appearance of Venus, and we got there first.
</p><p>
With so much detritus up in high orbit, and so many people based on the
Atlantic tower platform, it didn't take long for an old warship module to be
staffed out with a skeleton crew, and pushed off in the direction of the black
hole. The crew ended up being us, the second-shift engineering staff of the
Nagios. The warship was a decrepit 301 with no gun batteries to speak of, but
it did have one thing in its favour: the experimental coil we were dispatched
to try out.
</p><p>
I took on the role of pilot, simply because I'd done some strong gravity
training back at the Academy. Jackson was our chief engineer, and Fuller had
the day off, so he got roped in too. Three of us, and a crazy theory, to try
to change the war.
</p><p>
The theory was simple, when compared to others in the field of quantum
relativity. A black hole has a gravitational field, which radiates out in
lines, much like a magnetic field. Black holes also spin, which mean the
lines of gravitational field are moving all the time. Vassilev theorised
that a superconducting coil placed around the hole, near the Schwarzschild
radius, would cut through the field lines and generate an electrogravitic
field in the coil. It was impossible to even attempt a confirmation of the
theory at the time, since there were no black holes, and no superconductive
material to spare.
</p><p>
With the war, the situation was different. Even our old and broken 301 had a
few miles of ceramic-wire running to the weapons systems, which could carry
incredible amounts of charge. Measurements of the black hole mass put it
at around one thousandth of the sun's mass, which left the hole's Schwarzschild
radius at 30 metres: there would be plenty of wire for the coil. Getting the
coil into place, that was my job as ship's pilot.
</p><p>
As we came up towards Venus, I called down from the pilot's chair, into the
pit. "Jackson, get the ceramic down the back; let's give this hole a good
run."
</p><p>
It's not easy to steer a course around any strong gravity source, as we'd all
found out when the Weichinger carrier came too close to an enemy neutron
barrage: it had been torn clean in half by the tidal forces. A black hole was
more predictable, but much scarier at the same time. At least with a neutron
barrage, it was possible to come out the other side.
</p><p>
I'd done this kind of thing in simulators before, with a whole term of
spaceflight at the Academy focussed on getting around when strong gravity was
in the area. One thing you never expect is that the outside universe gets
smaller. We were close enough to the hole now, that I could barely see the
Earth as a small point in what seemed like the far distance, and stars were
beginning to show trails as we moved.
</p><p>
The 301 wasn't a highly manouverable warship at the height of its career, over
thirty years ago: it was often referred to as the Bucket Class by the current
cadets of the Academy. Moving around near a black hole was another adventure,
with the constant tug to the left as I wound the ship anti-clockwise around
the point.
</p><p>
"For what it's worth," Fuller called up from the cargo hold, "we're nearly out
of gas for the manouvering thrusters."
</p><p>
"We're low on everything," I said in reply. "No worries, I'm nearly done
here."
</p><p>
The hole was at least uniform, so it was pretty short work to get the coil
deployed in four loops around its equator. Jackson came up the ladder to the
viewscreen, while Fuller stayed down in the hold to get the coil's ends into
a power meter. Based on the shape of the black hole, and how stationary I could
keep the ship against it, we were looking at maybe three hundred gigawatts: not
bad for a proof of concept.
</p><p>
Fuller fired up the meter, and there was silence for a few seconds. "Er.
Jackson, Irvine? You'll want to see this."
</p><p>
"I'm holding the ship straight," I answered. "Do I need to come down there to
see what the meter says?"
</p><p>
"Well, it's off the scale, and the scale goes up to a terawatt."
</p><p>
Jackson looked down into the pit with a slightly incredulous look. "Nah, that
can't be right. Lemme get down there, I'll check the wire."
</p><p>
Even superconducting ceramic heats up when enough charge flows through it.
Jackson put his hand against the coil, and drew it back quickly. "That's, er,
warm. You might want to get someone else out here, Irvine; we might have more
than we bargained for here."
</p><hr><p>
That's how it started, of course. Eventually, we had wires criss-crossing that
hole and pulling out around ten terawatts: more than enough to feed a new
generation of powered weapons. Thanks to the hole, we fought the invaders off,
and Earth managed to claw its way out into the light.
</p><p>
A few years after the war ended, Stan Vassilev was awarded the Peace Prize,
which he found suitably ironic. It was his opinion that we'd bled our new
power source dry, and it would soon evaporate; a month later, the hole
vanished, and the 10TW of power went with it.
</p><p>
I still don't know where it came from, and why it showed up to help Earth when
it did. Religion's outlawed by the military, so I can't be a religious man,
but I do wonder sometimes. Even as an engineer, it strikes me as odd that
Earth was dealt such a massive stroke of luck: someone out there's looking
after our interests.
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Memory Banking</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/mbc" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Memory Banking" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/mbc</id>
 <summary>Continuing a series on the implementation of a GameBoy emulator, this part looks at how the basic memory map of the GameBoy can be expanded, to accommodate games that are larger than 32kB. The GameBoy uses a system of virtual memory banking to perform this expansion; the concepts of the banking controller are looked at, and an implementation offered.</summary>
 <category term="Series" />
 <published>Fri, 03 Dec 2010 19:20:30 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 9 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>Thus far in this series, we've been dealing with the loading and emulation of a simple <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory">memory map</a> for the GameBoy, with the entirety of the game ROM fitting into the lower half of memory. There aren't many games that fit into memory in full (Tetris is one of the few); most games are larger than this, and have to employ an independent mechanism to swap "banks" of game ROM into the GameBoy CPU's view.</p>
<p>Some of the first games in the GameBoy library were built with a Memory Bank Controller inside the cartridge, which did this job of swapping banks of ROM into view; over the years, various versions of the cartridge MBC were built for increasingly large games. In the particular example of the demo associated with this part, the first version of the MBC is used to handle the loading of a 64kB ROM.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-mbc1.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with MBC1 support</figcaption>
</figure>
<h2>Banking and memory expansion</h2>
<p>Through the years, many computer systems have had to deal with the problem of having too much program to fit into memory. Traditionally, there have been two ways to deal with this problem.</p>
<ul>
 <li><strong>Increase the address space</strong>: Build a new CPU with more address lines, allowing it to see and understand a larger amount of memory. This is the preferred solution, but requires significant time to redevelop the computer system in question, and may need more changes to be made in the supporting chipset for the CPU.</li>
 <li><strong>Virtual memory</strong>: This can either refer to the holding of chunks of RAM on disk, and their swapping in when required; or the swapping in of chunks of pre-written ROM when required. In both cases, the system hardware needs little extension but any software for the system has to be aware of the paging/banking system, in order to use it.</li>
</ul>
<p>Since the GameBoy is a fixed hardware platform with wide distribution, there's no way to increase the address space when larger games are produced; instead, the Memory Bank Controller built into the cartridge offers a way to switch 16kB banks of ROM into view. In addition to this, the MBC1 supports up to 32kB of "external RAM", which is writable memory in the cartridge; this can be banked into the <code>[A000-BFFF]</code> space in the memory map, if it's available.</p>
<p>In order to facilitate software that uses the MBC1, the first 16kB bank of ROM (bank 0) is fixed at address <code>0000</code>; the second half of the ROM space can be made into a window on any ROM bank between 1 and 127, for a maximum ROM size of 2048kB. One of the oddities of the MBC1 is that it deals internally in 32's: banks #32, #64 and #96 are inaccessible, since they're treated within the banking system as bank #0. This means that 125 banks apart from the fixed bank #0 are usable.</p>
<p>There are four registers within the MBC1 chip, that allow for switching of banks for the ROM and RAM; these can be changed by writing to the (normally read-only) ROM space anywhere within a certain range. The details are given in the below table.</p>
<figure>
 <table>
  <thead><tr><th>Locations</th><th>Register</th><th>Details</th></tr></thead>
  <tbody>
   <tr><td>0000-1FFF</td><td>Enable external RAM</td><td>4 bits wide; value of<br>0x0A enables RAM,<br>any other value disables</td></tr>
   <tr><td>2000-3FFF</td><td>ROM bank (low 5 bits)</td><td>Switch between banks 1-31 (value 0 is seen as 1)</td></tr>
   <tr><td>4000-5FFF</td><td>ROM bank (high 2 bits)<br>RAM bank</td><td>ROM mode: switch ROM bank "set" {1-31}-{97-127}<br>RAM mode: switch RAM bank 0-3</td></tr>
   <tr><td>6000-7FFF</td><td>Mode</td><td>0: ROM mode (no RAM banks, up to 2MB ROM)<br>1: RAM mode (4 RAM banks, up to 512kB ROM)</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: MBC1 register set</figcaption>
</figure>
<h2>MBCs and the cartridge header</h2>
<p>Since there are multiple kinds of controller for banking, any given game must state which MBC is used, in the cartridge header data. This is the first chunk of data in the cartridge ROM, and follows a specific format.</p>
<figure>
 <table>
  <thead><tr><th>Location(s)</th><th>Value</th><th>Size<br>(bytes)</th><th>Details</th></tr></thead>
  <tbody>
   <tr><td>0100-0103h</td><td>Entry point</td><td>4</td><td>Where the game starts<br>Usually "NOP; JP 0150h"</td></tr>
   <tr><td>0104-0133h</td><td>Nintendo logo</td><td>48</td><td>Used by the BIOS to verify checksum</td></tr>
   <tr><td>0134-0143h</td><td>Title</td><td>16</td><td>Uppercase, padded with 0</td></tr>
   <tr><td>0144-0145h</td><td>Publisher</td><td>2</td><td>Used by newer GameBoy games</td></tr>
   <tr><td>0146h</td><td>Super GameBoy flag</td><td>1</td><td>Value of 3 indicates SGB support</td></tr>
   <tr><td>0147h</td><td>Cartridge type</td><td>1</td><td>MBC type/extras</td></tr>
   <tr><td>0148h</td><td>ROM size</td><td>1</td><td>Usually between 0 and 7<br>Size = 32kB &lt;&lt; [0148h]</td></tr>
   <tr><td>0149h</td><td>RAM size</td><td>1</td><td>Size of external RAM</td></tr>
   <tr><td>014Ah</td><td>Destination</td><td>1</td><td>0 for Japan market, 1 otherwise</td></tr>
   <tr><td>014Bh</td><td>Publisher</td><td>1</td><td>Used by older GameBoy games</td></tr>
   <tr><td>014Ch</td><td>ROM version</td><td>1</td><td>Version of the game, usually 0</td></tr>
   <tr><td>014Dh</td><td>Header checksum</td><td>1</td><td>Checked by BIOS before loading</td></tr>
   <tr><td>014E-014Fh</td><td>Global checksum</td><td>2</td><td>Simple summation, not checked</td></tr>
   <tr><td>0150h</td><td colspan="3">Start of game</td></tr>
  </tbody>
 </table>
 <figcaption>Table 2: Cartridge header format</figcaption>
</figure>
<p>In this particular case, we're interested in the value of <code>0147h</code>, the cartridge type. The cartridge type can be one of the following values, if an MBC1 is fitted to the cartridge:</p>
<figure>
 <table>
  <thead><tr><th>Value</th><th>Definition</th></tr></thead>
  <tbody>
   <tr><td>00h</td><td>No MBC</td></tr>
   <tr><td>01h</td><td>MBC1</td></tr>
   <tr><td>02h</td><td>MBC1 with external RAM</td></tr>
   <tr><td>03h</td><td>MBC1 with battery-backed external RAM</td></tr>
  </tbody>
 </table>
 <figcaption>Table 3: Cartridge type values pertaining to MBC1</figcaption>
</figure>
<p>For the purposes of this article, a system of battery backing will not be implemented for the external RAM; this feature is often used by games to save their state for later use, and will be looked at in more detail in a later part.</p>
<h2>Implementation of MBC1</h2>
<p>The memory bank controllers are an obvious manipulation of memory, and thus fit neatly into the MMU. Since the first ROM bank (bank #0) is fixed, an offset need only be maintained for the MBC to indicate where it's reading for the second bank. In order to allow for more MBC handling to be added later, an array of data can be used to hold the state of a given controller:</p>
<samp>
 <h3>MMU.js: MBC state and reset</h3>
 <pre>MMU = {
    <s>// MBC states</s>
    _mbc: [],

    <s>// Offset for second ROM bank</s>
    _romoffs: <var>0x4000</var>,

    <s>// Offset for RAM bank</s>
    _ramoffs: <var>0x0000</var>,

    <s>// Copy of the ROM's cartridge-type value</s>
    _carttype: <var>0</var>,

    reset: <kbd>function</kbd>()
    {
        ...

	<s>// In addition to previous reset code,
	// initialise MBC internal data</s>
	MMU._mbc[<var>0</var>] = {};
	MMU._mbc[<var>1</var>] = {
	    rombank: <var>0</var>,		<s>// Selected ROM bank</s>
	    rambank: <var>0</var>,		<s>// Selected RAM bank</s>
	    ramon: <var>0</var>,		<s>// RAM enable switch</s>
	    mode: <var>0</var>		<s>// ROM/RAM expansion mode</s>
	};

	MMU._romoffs = <var>0x4000</var>;
	MMU._ramoffs = <var>0x0000</var>;
    },

    load: <kbd>function</kbd>(file)
    {
        ...
	MMU._carttype = MMU._rom.<kbd>charCodeAt</kbd>(<var>0x0147</var>);
    }
}</pre>
</samp>
<p>As can be seen in the above code, the internal state of the MBC1's four registers is represented by an object within the MMU, associated with MBC type 1. When these are changed, the ROM and RAM offsets can be modified to point into the appropriate bank of memory; once the pointers are set, access to the memory can proceed almost as normal.</p>
<samp>
 <h3>MMU.js: MBC1-based access</h3>
 <pre>MMU = {
    rb: <kbd>function</kbd>(addr)
    {
    	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...

	    <s>// ROM (switched bank)</s>
	    <kbd>case</kbd> <var>0x4000</var>:
	    <kbd>case</kbd> <var>0x5000</var>:
	    <kbd>case</kbd> <var>0x6000</var>:
	    <kbd>case</kbd> <var>0x7000</var>:
	        <kbd>return</kbd> MMU._rom.<kbd>charCodeAt</kbd>(MMU._romoffs +
		                           (addr &amp; <var>0x3FFF</var>));

	    <s>// External RAM</s>
	    <kbd>case</kbd> <var>0xA000</var>:
	    <kbd>case</kbd> <var>0xB000</var>:
	        <kbd>return</kbd> MMU._eram[MMU._ramoffs +
		                 (addr &amp; <var>0x1FFF</var>)];
	}
    }
};</pre>
</samp>
<p>The calculation of these pointer offsets is performed when the MBC registers are written, as shown below.</p>
<samp>
 <h3>MMU.js: MBC1 control</h3>
 <pre>    wb: <kbd>function</kbd>(addr, val)
    {
        <kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    <s>// MBC1: External RAM switch</s>
	    <kbd>case</kbd> <var>0x0000</var>:
	    <kbd>case</kbd> <var>0x1000</var>:
	        <kbd>switch</kbd>(MMU._carttype)
		{
		    <kbd>case</kbd> <var>2</var>:
		    <kbd>case</kbd> <var>3</var>:
			MMU._mbc[<var>1</var>].ramon =
			    ((val &amp; <var>0x0F</var>) == <var>0x0A</var>) ? <var>1</var> : <var>0</var>;
			<kbd>break</kbd>;
		}
		<kbd>break</kbd>;

	    <s>// MBC1: ROM bank</s>
	    <kbd>case</kbd> <var>0x2000</var>:
	    <kbd>case</kbd> <var>0x3000</var>:
	        <kbd>switch</kbd>(MMU._carttype)
		{
		    <kbd>case</kbd> <var>1</var>:
		    <kbd>case</kbd> <var>2</var>:
		    <kbd>case</kbd> <var>3</var>:
		        <s>// Set lower 5 bits of ROM bank (skipping #0)</s>
			val &amp;= <var>0x1F</var>;
			<kbd>if</kbd>(!val) val = <var>1</var>;
			MMU._mbc[<var>1</var>].rombank =
			    (MMU._mbc[<var>1</var>].rombank &amp; <var>0x60</var>) + val;

			<s>// Calculate ROM offset from bank</s>
			MMU._romoffs = MMU._mbc[<var>1</var>].rombank * <var>0x4000</var>;
			<kbd>break</kbd>;
		}
		<kbd>break</kbd>;

	    <s>// MBC1: RAM bank</s>
	    <kbd>case</kbd> <var>0x4000</var>:
	    <kbd>case</kbd> <var>0x5000</var>:
	        <kbd>switch</kbd>(MMU._carttype)
		{
		    <kbd>case</kbd> <var>1</var>:
		    <kbd>case</kbd> <var>2</var>:
		    <kbd>case</kbd> <var>3</var>:
		    	<kbd>if</kbd>(MMU._mbc[<var>1</var>].mode)
			{
			    <s>// RAM mode: Set bank</s>
			    MMU._mbc[<var>1</var>].rambank = val &amp; <var>3</var>;
			    MMU._ramoffs = MMU._mbc[<var>1</var>].rambank * <var>0x2000</var>;
			}
			<kbd>else</kbd>
			{
			    <s>// ROM mode: Set high bits of bank</s>
			    MMU._mbc[<var>1</var>].rombank =
			    	(MMU._mbc[<var>1</var>].rombank &amp; <var>0x1F</var>) +
				((val &amp; <var>3</var>) &lt;&lt; <var>5</var>);
			
			    MMU._romoffs = MMU._mbc[<var>1</var>].rombank * <var>0x4000</var>;
			}
			<kbd>break</kbd>;
		}
		<kbd>break</kbd>;

	    <s>// MBC1: Mode switch</s>
	    <kbd>case</kbd> <var>0x6000</var>:
	    <kbd>case</kbd> <var>0x7000</var>:
	        <kbd>switch</kbd>(MMU._carttype)
		{
		    <kbd>case</kbd> <var>2</var>:
		    <kbd>case</kbd> <var>3</var>:
		    	MMU._mbc[<var>1</var>].mode = val &amp; <var>1</var>;
			<kbd>break</kbd>;
		}
		<kbd>break</kbd>;

	    ...

	    <s>// External RAM</s>
	    <kbd>case</kbd> <var>0xA000</var>:
	    <kbd>case</kbd> <var>0xB000</var>:
	        MMU._eram[MMU._ramoffs + (addr &amp; <var>0x1FFF</var>)] = val;
		<kbd>break</kbd>;
	}
    }</pre>
</samp>
<p>In the above control code, instances of MBC1 that are stated as having external RAM attached are the ones which have RAM banking. With this code in place, the demo shown in Figure 1 loads and runs properly; without the MBC1 handler, the code would crash while attempting to access sprite and background data for the display.</p>
<h2>Coming up</h2>
<p>Aside from being able to fit larger games into memory, one of the more important aspects of a game is the ability to keep time: a clock-based game, for example, is useless without some kind of timing mechanism on which to base its clock. As mentioned previously, many games use the vertical blanking interrupt for this timing, but some require a finer-grained time structure; this is provided in the GameBoy by a hardware timer, tied into the CPU clock.</p>
<p>The timer also provides a method of examining the CPU clock, which makes it useful as a seed for random number generators; Tetris, for example, picks its blocks using this functionality of the hardware timer. In the next part, I'll look at the details of how the timer works, and how it can be implemented.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Dec 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Power</title>
 <link href="https://imrannazar.com/scifi/power" rel="alternate" type="text/html" title="Sci-fi Shorts: Power" />
 <id>https://imrannazar.com/scifi/power</id>
 <summary>A spaceship crewman is faced with a Catch-22 while maintaining the engines. Flash sci-fi.</summary>
 <category term="Original Writings" />
 <published>Tue, 09 Nov 2010 19:39:48 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Mera sat at his station, watching the slow spin of the heavy water reactor as
it spat out brackish waste fluid. As the water cascaded through the generator,
he had another problem to solve: one of power.
</p><p>
The ship had always been furtive while hopping through space: making random
jumps like a fly being preyed upon. The engines were growing torpid with old
age, jumping less often and not as far, with progress deteriorating by the
day. The only way to fix things was to take them offline for refurbishment,
which left the ship stationary and open to attack.
</p><p>
The go-ahead had been given, budgeted to two hours: it generally took the
Alliance ships at least three to find them at rest stops, so two hours was
plenty. Mera shut down the reactor; as its spin slowed, he opened the engine
casing and saw the problem immediately.
</p><p>
Some of the waste water had crept into the engines, evaporated with the heat,
and left salt deposits encrusted around the antimatter injectors. This would
take more than two hours to fix; the ship would have to land on a safe planet
for a full overhaul of the injector matrix.
</p><p>
Mera closed up the casing, and fired up the reactor. Nothing happened: the
reactor had itself seized with salt. The catch was that the Jump engine needed
power from the reactor: without the Jump drive, they'd never get to a planet
before Alliance hordes were crawling over them.
</p><p>
Now they were screwed.
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Interrupts</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/interrupts" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Interrupts" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/interrupts</id>
 <summary>Game consoles, like all computers, offer the facility to break off execution of a program and handle events or triggers. The GameBoy is no exception, and most games utilise the vertical blanking interrupt as one of their primary tools for keeping time and refreshing the screen. In part 8 of the series on emulator development, I look at the concepts behind, and the implementation of interrupts.</summary>
 <category term="Series" />
 <published>Fri, 05 Nov 2010 21:03:20 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 8 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p><strong>Please note: This article has been updated to remove an incorrect interrupt handling procedure.</strong> --12th Nov, 2010</p>
<p>In the previous part, the foundations for simulating a game were laid, with the introduction of sprites. However, one aspect was missing from the emulator: the vertical blanking interrupt. In this part, interrupts as a whole will be introduced, and the blanking interrupt in particular will be implemented; once this has been done, the emulator will run Tetris.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-int.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with vertical blanking interrupt</figcaption>
</figure>
<p>Imagine that you have a computer with a network card, and some software that processes data from the network. From the perspective of the computer, data only comes in every so often, so you need some way for the software to know that new data has arrived. There are two ways for this to happen:</p>
<ul>
 <li><strong>Polling</strong>: The software asks the network card every so often whether new data has arrived. This is a simplistic way of doing things, but has disadvantages:
  <ul>
   <li>The software doesn't know about new data until its periodic check, which means a delay between the data arriving at the computer and it being handled by the software;</li>
   <li>Time has to be taken out on a periodic basis for the checks to be made, taking time away from other work even if no data has arrived;</li>
   <li>If the polling process handles one piece of new data each time it checks, but data is arriving at a faster rate, a backlog of data is created in the network card, and there's potential for some data to be lost;</li>
   <li>If there is no other work to be done, the software still has to check for data, which keeps the computer running at full speed with no work to do.</li>
  </ul>
 </li> 
 <li><strong>Interrupts</strong>: The network card informs the software that new data has arrived. This is a more complicated way of receiving data, with more steps involved, but it alleviates all the disadvantages of polling:
  <ul>
   <li>New data can be processed as soon as it arrives, with no delay between arrival and the data being handled;</li>
   <li>The software need only take time to handle data when there's definitely data to be handled, and the processing routines can be called as often as necessary to clear any backlogs;</li>
   <li>If there is no other work to be done, the computer can enter a low-power mode until the network card awakens it for new data.</li>
  </ul>
 </li>
</ul>
<h2>Interrupts and interrupt handlers</h2>
<p>It's obvious that the concept of interrupts is a useful one, but there are both hardware and software requirements for interrupts to work. In hardware terms, the CPU has to temporarily stop execution of what it's doing when an interrupt arrives, and instead begin execution of an interrupt handler (sometimes referred to as an Interrupt Service Routine). In the above scenario, a wire is run between the network card and the CPU, allowing the card to inform the CPU when data has arrived.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-int-hardware.png" alt="Hardware implementation of interrupts">
 <figcaption>Figure 2: Hardware implementation of interrupts</figcaption>
</figure>
<p>The CPU will check its interrupt inputs at the end of every instruction. If an interrupt signal has been given by some attached peripheral like the network card, steps are taken by the CPU to start the interrupt handler: the CPU will save the location where it left off normal execution, register the fact that the interrupt happened, and jump across to the handler.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-int-cpu.png" alt="CPU interrupt handling">
 <figcaption>Figure 3: CPU interrupt handling procedure</figcaption>
</figure>
<p>In the GameBoy, there are five different interrupt wires, feeding in from the various peripherals. Each one has its own ISR at a different address in memory; the list of interrupts is as follows.</p>
<figure>
 <table>
  <thead><tr><th>Interrupt</th><th>ISR address (hex)</th></tr></thead>
  <tbody>
   <tr><td>Vertical blank</td><td><code>0040</code></td></tr>
   <tr><td>LCD status triggers</td><td><code>0048</code></td></tr>
   <tr><td>Timer overflow</td><td><code>0050</code></td></tr>
   <tr><td>Serial link</td><td><code>0058</code></td></tr>
   <tr><td>Joypad press</td><td><code>0060</code></td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Interrupts in the GameBoy</figcaption>
</figure>
<p>In the case of the vertical blank, a wire is threaded into the bottom of the LCD; as soon as the GPU has finished scanning all the LCD lines and runs into the bottom of the screen, the interrupt fires and the CPU jumps to <code>0040</code>, executing the blanking ISR.</p>
<h2>Implementation: Interrupt flags</h2>
<p>Most CPUs contain a "master flag" for interrupts: they will only be handled by the CPU if this flag is enabled. The Z80 in the GameBoy is no exception, but there are additional registers that deal with the individual interrupts available in the GameBoy. These are memory registers, so they are handled by the memory management unit:</p>
<figure>
 <table>
  <thead><tr><th>Register</th><th>Location</th><th>Notes</th><th>Details</th></tr></thead>
  <tbody>
   <tr>
    <td>Interrupt<br>enable</td>
    <td><code>FFFF</code></td>
    <td>When bits are set,<br>the corresponding<br>interrupt can<br>be triggered</td>
    <td>
     <table>
      <thead><tr><th>Bit</th><th>When 0</th><th>When 1</th></tr></thead>
      <tbody>
       <tr><td>0</td><td>Vblank off</td><td>Vblank on</td></tr>
       <tr><td>1</td><td>LCD stat off</td><td>LCD stat on</td></tr>
       <tr><td>2</td><td>Timer off</td><td>Timer on</td></tr>
       <tr><td>3</td><td>Serial off</td><td>Serial on</td></tr>
       <tr><td>4</td><td>Joypad off</td><td>Joypad on</td></tr>
      </tbody>
     </table>
    </td>
   </tr>
   <tr>
    <td>Interrupt<br>flags</td>
    <td><code>FF0F</code></td>
    <td>When bits are set,<br>an interrupt<br>has happened</td>
    <td>Bits in the same<br>order as <code>FFFF</code></td>
   </tr>
  </tbody>
 </table>
 <figcaption>Table 2: Interrupt flags in the MMU</figcaption>
</figure>
<p>Since these are memory registers, their implementation is something for the MMU:</p>
<samp>
 <h3>MMU.js: Interrupt flags</h3>
 <pre>MMU = {
    _ie: <var>0</var>,
    _if: <var>0</var>,

    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// Zero-page</s>
		    <kbd>case</kbd> <var>0xF00</var>:
		    	<kbd>if</kbd>(addr == <var>0xFFFF</var>)
			{
			    <kbd>return</kbd> MMU._ie;
			}
		        <kbd>else if</kbd>(addr &gt;= <var>0xFF80</var>)
			{
			    <kbd>return</kbd> MMU._zram[addr &amp; <var>0x7F</var>];
			}
			<kbd>else</kbd>
			{
			    <s>// I/O control handling</s>
			    <kbd>switch</kbd>(addr &amp; <var>0x00F0</var>)
			    {
			    	<kbd>case</kbd> <var>0x00</var>:
				    <kbd>if</kbd>(addr == <var>0xFF0F</var>) <kbd>return</kbd> MMU._if;
				    <kbd>break;</kbd>
			    	...
			    }
			    <kbd>return</kbd> <var>0</var>;
			}
		}
	}
    },
    ...
};</pre>
</samp>
<p>The Z80's "master enable" switch is, in a similar manner, something for the Z80 implementation. The CPU provides opcodes for software to flick the master enable into either On or Off position, so these will also need to be implemented:</p>
<samp>
 <h3>Z80.js: Interrupt master enable</h3>
 <pre>Z80 = {
    _r: {
        ime: <var>0</var>,
        ...
    },

    reset: <kbd>function</kbd>()
    {
        ...
	Z80._r.ime = <var>1</var>;
    },

    <s>// Disable IME</s>
    DI: <kbd>function</kbd>()
    {
    	Z80._r.ime = <var>0</var>;
	Z80._r.m = <var>1</var>;
	Z80._r.t = <var>4</var>;
    },

    <s>// Enable IME</s>
    EI: <kbd>function</kbd>()
    {
    	Z80._r.ime = <var>1</var>;
	Z80._r.m = <var>1</var>;
	Z80._r.t = <var>4</var>;
    }
};</pre>
</samp>
<h2>Implementation: Interrupt handling</h2>
<p>With the interrupt flags in place, the main execution loop can be redeveloped, to fall more in line with the execution path from figure 3. After execution, the interrupt flags need checking to see whether an enabled interrupt has occurred; if it has, its handler can be called.</p>
<samp>
 <h3>Z80.js: Vblank interrupt handler</h3>
 <pre>Z80 = {
    _ops: {
	...

        <s>// Start vblank handler (0040h)</s>
        RST40: <kbd>function</kbd>()
        {
            <s>// Disable further interrupts</s>
    	    Z80._r.ime = <var>0</var>;
    
    	    <s>// Save current SP on the stack</s>
    	    Z80._r.sp -= <var>2</var>;
    	    MMU.ww(Z80._r.sp, Z80._r.pc);
    
    	    <s>// Jump to handler</s>
    	    Z80._r.pc = <var>0x0040</var>;
	    Z80._r.m = <var>3</var>;
    	    Z80._r.t = <var>12</var>;
        },
        
        <s>// Return from interrupt (called by handler)</s>
        RETI: <kbd>function</kbd>()
        {
	    <s>// Restore interrupts</s>
	    Z80._r.ime = <var>1</var>;

	    <s>// Jump to the address on the stack</s>
	    Z80._r.pc = MMU.rw(Z80._r.sp);
	    Z80._r.sp += <var>2</var>;

	    Z80._r.m = <var>3</var>;
	    Z80._r.t = <var>12</var>;
        }
    }
};

<kbd>while</kbd>(<var>true</var>)
{
    <s>// Run execute for this instruction</s>
    <kbd>var</kbd> op = MMU.rc(Z80._r.pc++);
    Z80._map[op]();
    Z80._r.pc &amp;= <var>65535</var>;
    Z80._clock.m += Z80._r.m;
    Z80._clock.t += Z80._r.t;
    Z80._r.m = <var>0</var>;
    Z80._r.t = <var>0</var>;

    <s>// If IME is on, and some interrupts are enabled in IE, and
    // an interrupt flag is set, handle the interrupt</s>
    <kbd>if</kbd>(Z80._r.ime &amp;&amp; MMU._ie &amp;&amp; MMU._if)
    {
        <s>// Mask off ints that aren't enabled</s>
        <kbd>var</kbd> ifired = MMU._ie &amp; MMU._if;

	<kbd>if</kbd>(ifired &amp; <var>0x01</var>)
	{
	    MMU._if &amp;= (<var>255</var> - <var>0x01</var>);
	    Z80._ops.RST40();
	}
    }

    Z80._clock.m += Z80._r.m;
    Z80._clock.t += Z80._r.t;
}</pre>
</samp>
<h2>Next time: Bigger games</h2>
<p>As shown in Figure 1, the emulator has reached a reasonable stage: it's able to emulate a released game in at least some form. It does, however, have the problem of game size. Tetris is a 32kB ROM, and fits perfectly into the "ROM" space in the <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory">memory map</a>. Games tend to have larger ROMs than this, and the cartridge follows a process of mapping portions of the ROM into memory. Next time, I'll look at the simplest available form of ROM mapping for the GameBoy, and its implementation on a 64kB game ROM.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Nov 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Sprites</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/sprites" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Sprites" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/sprites</id>
 <summary>The basis of most games is the movement of objects over a background landscape. In this part of the series on emulation development, I take a look at how the GameBoy produces movable objects, and how the process can be emulated in JavaScript.</summary>
 <category term="Series" />
 <published>Sun, 10 Oct 2010 22:34:05 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 7 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>Previously in this series, the emulator was extended to enable keypad input, which meant that a game of tic-tac-toe could be played. The problem left by this was that the game had to be played blind: there was no indication of where the next move would be made, nor of to where on the game a keypress would move you. Traditionally, two-dimensional gaming consoles have solved this issue through the use of sprites: movable object blocks that can be placed independently of the background, and which contain data separate to that of the background.</p>
<p>The GameBoy is no exception in this regard: it provides for sprites to be placed above or below the background, and multiple sprites to be on screen at the same time. Once this has been implemented in the emulator, the tic-tac-toe game runs as below.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-gpu-sprite.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with sprites</figcaption>
</figure>
<h2>Introduction: GameBoy sprites</h2>
<p>GameBoy sprites are graphic tiles, just like those used for the background: this means that each sprite is 8x8 pixels. As stated above, a sprite can be placed anywhere on the screen, including halfway or all the way off-screen, and it can be placed above or below the background. What this means technically is that sprites below the background show through where the background has colour value 0.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-gpu-sprite-prio.png" alt="Sprite priorities">
 <figcaption>Figure 2: Sprite priorities</figcaption>
</figure>
<p>In the above figure, the sprite above the background shows the background through the middle of it, since these pixels in the sprite are set to colour 0; in the same way, the background lets through the sprites below it where the background colour is 0. In order to simulate this in an emulator, the simplest procedure would be to render the sprites below the background, then the background itself, and finally the sprites above it. However, this is a somewhat naive algorithm, since it duplicates the sprite rendering process; it's simpler instead to draw the background first, then work out whether a given pixel in the sprite should appear based on its priority and the background colour at that position.</p>
<samp>
 <h3>Pseudocode for sprite rendering</h3>
 <pre>For each row in sprite
    If this row is on screen
        For each pixel in row
            If this pixel is on screen
	        If this pixel is transparent
		    <s>* Do nothing</s>
		Else
		    If the sprite has priority
		        <var>Draw pixel</var>
		    Else if this pixel in the background is 0
		        <var>Draw pixel</var>
		    Else
		        <s>* Do nothing</s>
		    End If
		End If
	    End If
        End For
    End If
End For</pre>
</samp>
<p>One additional complication to the GameBoy sprite system is that a sprite can be "flipped" horizontally or vertically by the hardware, at the time it's rendered; this saves space in the game, since (for example) a spaceship flying backwards can be represented by the same sprite as forward motion, with the appropriate flip applied.</p>
<h2>Sprite data: Object Attribute Memory</h2>
<p>The GameBoy can hold information about 40 sprites, in a dedicated region of memory called Object Attribute Memory (OAM). Each of the 40 sprites has four bytes of data in the OAM associated with it, as detailed below.</p>
<figure>
 <table>
  <thead><tr><th>Byte</th><th>Description</th></tr></thead>
  <tbody>
   <tr><td>0</td><td>Y-coordinate of top-left corner<br>(Value stored is Y-coordinate minus 16)</td></tr>
   <tr><td>1</td><td>X-coordinate of top-left corner<br>(Value stored is X-coordinate minus 8)</td></tr>
   <tr><td>2</td><td>Data tile number</td></tr>
   <tr><td>3</td><td>Options
    <table>
     <thead><tr><th>Bit</th><th>Description</th><th>When 0</th><th>When 1</th></tr></thead>
     <tbody>
      <tr><td>7</td><td>Sprite/background priority</td><td>Above background</td><td>Below background<br>(except colour 0)</td></tr>
      <tr><td>6</td><td>Y-flip</td><td>Normal</td><td>Vertically flipped</td></tr>
      <tr><td>5</td><td>X-flip</td><td>Normal</td><td>Horizontally flipped</td></tr>
      <tr><td>4</td><td>Palette</td><td>OBJ palette #0</td><td>OBJ palette #1</td></tr>
     </tbody>
    </table>
   </td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: OAM data for a sprite</figcaption>
</figure>
<p>In order to more easily access this information when it comes to rendering a scanline, it's useful to build a structure to hold the sprite data, which is filled in based on the contents of the OAM. When data is written to the OAM, the MMU in consort with the graphics emulation can update this structure for later use. An implementation of this would be as follows.</p>
<samp>
 <h3>MMU.js: OAM access</h3>
 <pre>    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// OAM</s>
		    <kbd>case</kbd> <var>0xE00</var>:
		        <kbd>return</kbd> (addr &lt; <var>0xFEA0</var>) ? GPU._oam[addr &amp; <var>0xFF</var>] : 0;
		}
	}
    },

    wb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// OAM</s>
		    <kbd>case</kbd> <var>0xE00</var>:
		        <kbd>if</kbd>(addr &lt; <var>0xFEA0</var>) GPU._oam[addr &amp; <var>0xFF</var>] = val;
			GPU.buildobjdata(addr - <var>0xFE00</var>, val);
			<kbd>break</kbd>;
		}
	}
    }</pre>
 <h3>GPU.js: Sprite structure</h3>
 <pre>    _oam: [],
    _objdata: [],

    reset: <kbd>function</kbd>()
    {
        <s>// In addition to previous reset code:</s>
	<kbd>for</kbd>(<kbd>var</kbd> i=<var>0</var>, n=<var>0</var>; i &lt; <var>40</var>; i++, n+=<var>4</var>)
	{
	    GPU._oam[n + <var>0</var>] = <var>0</var>;
	    GPU._oam[n + <var>1</var>] = <var>0</var>;
	    GPU._oam[n + <var>2</var>] = <var>0</var>;
	    GPU._oam[n + <var>3</var>] = <var>0</var>;
	    GPU._objdata[i] = {
	        <var>'y'</var>: <var>-16</var>, <var>'x'</var>: <var>-8</var>,
		<var>'tile'</var>: <var>0</var>, <var>'palette'</var>: <var>0</var>,
		<var>'xflip'</var>: <var>0</var>, <var>'yflip'</var>: <var>0</var>, <var>'prio'</var>: <var>0</var>, <var>'num'</var>: i
	    };
	}
    },

    buildobjdata: <kbd>function</kbd>(addr, val)
    {
	<kbd>var</kbd> obj = addr &gt;&gt; <var>2</var>;
	<kbd>if</kbd>(obj &lt; <var>40</var>)
	{
	    <kbd>switch</kbd>(addr &amp; <var>3</var>)
	    {
	        <s>// Y-coordinate</s>
	        <kbd>case</kbd> <var>0</var>: GPU._objdata[obj].y = val-<var>16</var>; <kbd>break</kbd>;
		
		<s>// X-coordinate</s>
		<kbd>case</kbd> <var>1</var>: GPU._objdata[obj].x = val-<var>8</var>; <kbd>break</kbd>;

		<s>// Data tile</s>
		<kbd>case</kbd> <var>2</var>: GPU._objdata[obj].tile = val; <kbd>break</kbd>;

		<s>// Options</s>
		<kbd>case</kbd> <var>3</var>:
		    GPU._objdata[obj].palette = (val &amp; <var>0x10</var>) ? <var>1</var> : <var>0</var>;
		    GPU._objdata[obj].xflip   = (val &amp; <var>0x20</var>) ? <var>1</var> : <var>0</var>;
		    GPU._objdata[obj].yflip   = (val &amp; <var>0x40</var>) ? <var>1</var> : <var>0</var>;
		    GPU._objdata[obj].prio    = (val &amp; <var>0x80</var>) ? <var>1</var> : <var>0</var>;
		    <kbd>break</kbd>;
	    }
	}
    }</pre>
</samp>
<h2>Sprite palettes</h2>
<p>As hinted above, the GPU offers a choice of two palettes for the sprites: each of the 40 sprites can use one of the two palettes, as specified in its OAM entry. These object palettes are stored in the GPU, in addition to the background palette, and can be changed through I/O registers in much the same manner as the palette for the background.</p>
<samp>
 <h3>GPU.js: Sprite palette handling</h3>
 <pre>    _pal: {
        bg: [],
	obj0: [],
	obj1: []
    },

    wb: <kbd>function</kbd>(addr)
    {
        <kbd>switch</kbd>(addr)
	{
	    <s>// ...</s>
	    <s>// Background palette</s>
	    <kbd>case</kbd> <var>0xFF47</var>:
	        <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>4</var>; i++)
		{
		    <kbd>switch</kbd>((val &gt;&gt; (i * <var>2</var>)) &amp; <var>3</var>)
		    {
		        <kbd>case</kbd> <var>0</var>: GPU._pal.bg[i] = [<var>255</var>,<var>255</var>,<var>255</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>1</var>: GPU._pal.bg[i] = [<var>192</var>,<var>192</var>,<var>192</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>2</var>: GPU._pal.bg[i] = [ <var>96</var>, <var>96</var>, <var>96</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>3</var>: GPU._pal.bg[i] = [  <var>0</var>,  <var>0</var>,  <var>0</var>,<var>255</var>]; <kbd>break</kbd>;
		    }
		}
		<kbd>break</kbd>;

	    <s>// Object palettes</s>
	    <kbd>case</kbd> <var>0xFF48</var>:
	        <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>4</var>; i++)
		{
		    <kbd>switch</kbd>((val &gt;&gt; (i * <var>2</var>)) &amp; <var>3</var>)
		    {
		        <kbd>case</kbd> <var>0</var>: GPU._pal.obj0[i] = [<var>255</var>,<var>255</var>,<var>255</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>1</var>: GPU._pal.obj0[i] = [<var>192</var>,<var>192</var>,<var>192</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>2</var>: GPU._pal.obj0[i] = [ <var>96</var>, <var>96</var>, <var>96</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>3</var>: GPU._pal.obj0[i] = [  <var>0</var>,  <var>0</var>,  <var>0</var>,<var>255</var>]; <kbd>break</kbd>;
		    }
		}
		<kbd>break</kbd>;

	    <kbd>case</kbd> <var>0xFF49</var>:
	        <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>4</var>; i++)
		{
		    <kbd>switch</kbd>((val &gt;&gt; (i * <var>2</var>)) &amp; <var>3</var>)
		    {
		        <kbd>case</kbd> <var>0</var>: GPU._pal.obj1[i] = [<var>255</var>,<var>255</var>,<var>255</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>1</var>: GPU._pal.obj1[i] = [<var>192</var>,<var>192</var>,<var>192</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>2</var>: GPU._pal.obj1[i] = [ <var>96</var>, <var>96</var>, <var>96</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>3</var>: GPU._pal.obj1[i] = [  <var>0</var>,  <var>0</var>,  <var>0</var>,<var>255</var>]; <kbd>break</kbd>;
		    }
		}
		<kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Rendering sprites</h2>
<p>The GameBoy graphics system renders each line of the screen as it's encountered: this includes not only the background, but the sprites below and above it. In other words, rendering of the sprites must be added to the scanline renderer, as a process that occurs after drawing the background. Just as with the background, there's a switch to enable sprites within the LCDC register, and this must be added to the I/O handling for the GPU.</p>
<p>Since a sprite can be anywhere on the screen, including positioned somewhere off-screen, the renderer has to check which sprites are positioned within the current scanline. The simplest algorithm for this is to check the position of each one, and render the appropriate line of the sprite if it falls within the bounds of the scanline. The sprite data can be retrieved in the same way as it is for the background, through the pre-calculated tile set. An example of these things brought together is as follows.</p>
<samp>
 <h3>GPU.js: Rendering a scanline with sprites</h3>
 <pre>    renderscan: <kbd>function</kbd>()
    {
        <s>// Scanline data, for use by sprite renderer</s>
	<kbd>var</kbd> scanrow = [];

        <s>// Render background if it's switched on</s>
        <kbd>if</kbd>(GPU._switchbg)
	{
	    <kbd>var</kbd> mapoffs = GPU._bgmap ? <var>0x1C00</var> : <var>0x1800</var>;
	    mapoffs += ((GPU._line + GPU._scy) &amp; <var>255</var>) &gt;&gt; <var>3</var>;
	    <kbd>var</kbd> lineoffs = (GPU._scx &gt;&gt; <var>3</var>);
	    <kbd>var</kbd> y = (GPU._line + GPU._scy) &amp; <var>7</var>;
	    <kbd>var</kbd> x = GPU._scx &amp; <var>7</var>;
	    <kbd>var</kbd> canvasoffs = GPU._line * <var>160</var> * <var>4</var>;
	    <kbd>var</kbd> colour;
	    <kbd>var</kbd> tile = GPU._vram[mapoffs + lineoffs];

	    <s>// If the tile data set in use is #1, the
	    // indices are signed; calculate a real tile offset</s>
	    <kbd>if</kbd>(GPU._bgtile == <var>1</var> &amp;&amp; tile &lt; <var>128</var>) tile += <var>256</var>;

	    <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>160</var>; i++)
	    {
	        <s>// Re-map the tile pixel through the palette</s>
	        colour = GPU._pal.bg[GPU._tileset[tile][y][x]];

	        <s>// Plot the pixel to canvas</s>
	        GPU._scrn.data[canvasoffs+<var>0</var>] = colour[<var>0</var>];
	        GPU._scrn.data[canvasoffs+<var>1</var>] = colour[<var>1</var>];
	        GPU._scrn.data[canvasoffs+<var>2</var>] = colour[<var>2</var>];
	        GPU._scrn.data[canvasoffs+<var>3</var>] = colour[<var>3</var>];
	        canvasoffs += <var>4</var>;

		<s>// Store the pixel for later checking</s>
		scanrow[i] = GPU._tileset[tile][y][x];

	        <s>// When this tile ends, read another</s>
	        x++;
	        <kbd>if</kbd>(x == <var>8</var>)
	        {
	    	    x = <var>0</var>;
	    	    lineoffs = (lineoffs + <var>1</var>) &amp; <var>31</var>;
	    	    tile = GPU._vram[mapoffs + lineoffs];
	    	    <kbd>if</kbd>(GPU._bgtile == <var>1</var> &amp;&amp; tile &lt; <var>128</var>) tile += <var>256</var>;
	        }
	    }
	}

	<s>// Render sprites if they're switched on</s>
	<kbd>if</kbd>(GPU._switchobj)
	{
	    <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>40</var>; i++)
	    {
	        <kbd>var</kbd> obj = GPU._objdata[i];

		<s>// Check if this sprite falls on this scanline</s>
		<kbd>if</kbd>(obj.y &lt;= GPU._line &amp;&amp; (obj.y + <var>8</var>) &gt; GPU._line)
		{
		    <s>// Palette to use for this sprite</s>
		    <kbd>var</kbd> pal = obj.pal ? GPU._pal.obj1 : GPU._pal.obj0;

        	    <s>// Where to render on the canvas</s>
		    <kbd>var</kbd> canvasoffs = (GPU._line * <var>160</var> + obj.x) * <var>4</var>;

		    <s>// Data for this line of the sprite</s>
		    <kbd>var</kbd> tilerow;

		    <s>// If the sprite is Y-flipped,
		    // use the opposite side of the tile</s>
		    <kbd>if</kbd>(obj.yflip)
		    {
		        tilerow = GPU._tileset[obj.tile]
			                      [<var>7</var> - (GPU._line - obj.y)];
		    }
		    <kbd>else</kbd>
		    {
		        tilerow = GPU._tileset[obj.tile]
			                      [GPU._line - obj.y];
		    }

		    <kbd>var</kbd> colour;
		    <kbd>var</kbd> x;

		    <kbd>for</kbd>(<kbd>var</kbd> x = <var>0</var>; x &lt; <var>8</var>; x++)
		    {
		        <s>// If this pixel is still on-screen, AND
			// if it's not colour 0 (transparent), AND
			// if this sprite has priority OR shows under the bg
			// then render the pixel</s>
			<kbd>if</kbd>((obj.x + x) &gt;= <var>0</var> &amp;&amp; (obj.x + x) &lt; <var>160</var> &amp;&amp;
			   tilerow[x] &amp;&amp;
			   (obj.prio || !scanrow[obj.x + x]))
			{
		            <s>// If the sprite is X-flipped,
			    // write pixels in reverse order</s>
			    colour = pal[tilerow[obj.xflip ? (<var>7</var>-x) : x]];

			    GPU._scrn.data[canvasoffs+<var>0</var>] = colour[<var>0</var>];
			    GPU._scrn.data[canvasoffs+<var>1</var>] = colour[<var>1</var>];
			    GPU._scrn.data[canvasoffs+<var>2</var>] = colour[<var>2</var>];
			    GPU._scrn.data[canvasoffs+<var>3</var>] = colour[<var>3</var>];

			    canvasoffs += <var>4</var>;
			}
		    }
		}
	    }
	}
    },
    
    rb: <kbd>function</kbd>(addr)
    {
        <kbd>switch</kbd>(addr)
	{
	    <s>// LCD Control</s>
	    <kbd>case</kbd> <var>0xFF40</var>:
	        <kbd>return</kbd> (GPU._switchbg  ? <var>0x01</var> : <var>0x00</var>) |
		       (GPU._switchobj ? <var>0x02</var> : <var>0x00</var>) |
		       (GPU._bgmap     ? <var>0x08</var> : <var>0x00</var>) |
		       (GPU._bgtile    ? <var>0x10</var> : <var>0x00</var>) |
		       (GPU._switchlcd ? <var>0x80</var> : <var>0x00</var>);

	    <s>// ...</s>
	}
    },

    wb: <kbd>function</kbd>(addr, val)
    {
        <kbd>switch</kbd>(addr)
	{
	    <s>// LCD Control</s>
	    <kbd>case</kbd> <var>0xFF40</var>:
	        GPU._switchbg  = (val &amp; <var>0x01</var>) ? <var>1</var> : <var>0</var>;
		GPU._switchobj = (val &amp; <var>0x02</var>) ? <var>1</var> : <var>0</var>;
		GPU._bgmap     = (val &amp; <var>0x08</var>) ? <var>1</var> : <var>0</var>;
		GPU._bgtile    = (val &amp; <var>0x10</var>) ? <var>1</var> : <var>0</var>;
		GPU._switchlcd = (val &amp; <var>0x80</var>) ? <var>1</var> : <var>0</var>;
		<kbd>break</kbd>;

	    <s>// ...</s>
	}
    }</pre>
</samp>
<h2>Coming up</h2>
<p>With sprites in place, basic games like the tic-tac-toe running in Figure 1 can work in full. Many games, however, will not run without something else: a method of determining when the screen can be redrawn. Almost every game will perform a "refresh" of the screen data while the screen is in vertical blanking, since changes to the screen won't show up until the next time the GPU comes to draw a frame.</p>
<p>Basic games and demos sometimes do this by checking whether the GPU has hit line #144 in its redrawing process, but this takes up a lot of processing power in repeated looping. The more common method is for the game to be informed when an event has occurred: this message is referred to as an interrupt. In the next part, I'll take a look at the vertical blanking interrupt in particular, and how it can be simulated to provide this message passing process to an emulated game.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Oct 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Input</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/input" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Input" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/input</id>
 <summary>Part six of the series examines the issue of how a player interacts with the GameBoy, taking a look at the hardware layout of the keypad, and how the layout can be implemented as part of an emulator. The particular issues thrown up by a JavaScript emulation are looked at, including basic event handling and how events can be passed to the keypad handler.</summary>
 <category term="Series" />
 <published>Sun, 19 Sep 2010 21:41:40 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 6 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>With a working emulator and interface developed over the previous five parts, the emulation system is able to run a basic test ROM, and produce graphical output. What the emulator is currently unable to do is take keypresses as keypad input, and feed them through to the ROM under test; in order for this to be done, the keypad's influence on the I/O registers must be emulated.</p>
<p>With the addition of keypad I/O, the emulator runs as follows.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-key.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with key input</figcaption>
</figure>
<h2>The keypad</h2>
<p>The GameBoy has a single method of input, an eight-key pad out of which any number of keys can be depressed. With most keyboards, the keys are laid out in a grid of columns and rows: these can be treated as wires, between which a key can form a connection. When one of the columns is activated, any rows connected to that column will also activate, and the hardware is able to detect the active rows to determine the currently pressed keys.</p>
<p>With the GameBoy, the keyboard grid has two columns and four rows, which has the advantage that all the required connections can be made within one 8-bit I/O register.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-key-wires.png" alt="Keyboard wiring">
 <figcaption>Figure 2: Keyboard wiring</em>
</figure>
<p>Since all six lines are tied to the same register, the GameBoy procedure for reading a key is slightly convoluted:</p>
<ul>
 <li>Write either 0x10 or 0x20 to JOYP: this will activate either bit 4 or 5, one of the column lines;</li>
 <li>Wait a few cycles for the row connections to propagate to JOYP;</li>
 <li>Check the low four bits of JOYP, to find which rows were active for this column.</li>
</ul>
<h2>Implementation of the keypad</h2>
<p>Writing code to simulate keypad presses is relatively simple, but two factors complicate the issue: allowing for a column to be set in the grid before rows are read, and the keypress codes that are used by JavaScript. In order to accommodate the two columns, two values must be used by the emulation, each of which holds the intersections between that column and the rows. One additional factor to take into account is that the values are reversed for the keypad: a row is left at high voltage by default, and is dropped to zero voltage when it intersects a column. This is interpreted by the I/O register as the row bits being 1 for no key pressed, and 0 for a keypress.</p>
<p>The JavaScript <code>keydown</code> and <code>keyup</code> events can be used to find out when a key has been pressed or released; tying these into the keypad handler can be done in the following manner.</p>
<samp>
 <h3>Key.js: Object interface</h3>
 <pre>KEY = {
    _rows: [<var>0x0F</var>, <var>0x0F</var>],
    _column: <var>0</var>,

    reset: <kbd>function</kbd>()
    {
        KEY._rows = [<var>0x0F</var>, <var>0x0F</var>];
	KEY._column = <var>0</var>;
    },

    rb: <kbd>function</kbd>(addr)
    {
        <kbd>switch</kbd>(KEY._column)
	{
	    <kbd>case</kbd> <var>0x10</var>: <kbd>return</kbd> KEY._rows[<var>0</var>];
	    <kbd>case</kbd> <var>0x20</var>: <kbd>return</kbd> KEY._rows[<var>1</var>];
	    <kbd>default</kbd>: <kbd>return</kbd> <var>0</var>;
	}
    },

    wb: <kbd>function</kbd>(addr, val)
    {
        KEY._column = val &amp; <var>0x30</var>;
    },

    kdown: <kbd>function</kbd>(e)
    {
        <s>// Reset the appropriate bit</s>
    },

    kup: <kbd>function</kbd>(e)
    {
        <s>// Set the appropriate bit</s>
    }
};

<kbd>window</kbd>.onkeydown = KEY.kdown;
<kbd>window</kbd>.onkeyup = KEY.kup;</pre>
</samp>
<p>In addition to this, the MMU must be extended to handle the keypad I/O register, with an addition to the zero-page handling routines; an example of this is given below.</p>
<samp>
 <h3>MMU.js: Keypad I/O interface</h3>
 <pre>    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// Zero-page</s>
		    <kbd>case</kbd> <var>0xF00</var>:
		        <kbd>if</kbd>(addr &gt;= <var>0xFF80</var>)
			{
			    <kbd>return</kbd> MMU._zram[addr &amp; <var>0x7F</var>];
			}
			<kbd>else if</kbd>(addr &gt;= <var>0xFF40</var>)
			{
			    <s>// GPU (64 registers)</s>
			    <kbd>return</kbd> GPU.rb(addr);
			}
			<kbd>else switch</kbd>(addr &amp; <var>0x3F</var>)
			{
			    <kbd>case</kbd> <var>0x00</var>: <kbd>return</kbd> KEY.rb();
			    <kbd>default</kbd>: <kbd>return</kbd> <var>0</var>;
			}
		}
	}
    }</pre>
</samp>
<p>With the keypad handler plumbed in, the remaining issue is the handling of keypresses, and the ability of the keypad code to distinguish between different keys being pressed. This can be done through the JavaScript <code>event</code> object; any event that runs through the browser, such as a mouse click or a keypress, will be passed to the code if it's requested, along with an object that describes the event that's just occurred. In the case of a keypress, the <code>event</code> object contains a character code and a "key scan" code, which both describe the key in question.</p>
<p>Through testing by <a href="http://www.quirksmode.org/js/keys.html">Peter-Paul Koch</a>, it has been determined that the character code passed by browsers to JavaScript code is unreliable, and will change depending on which browser is used. The only case on which all browsers agree is the key-scan code produced for <code>keyup</code> and <code>keydown</code> events; in any browser, pressing a given key will yield a particular value.</p>
<p>For the purposes of this emulator, eight keys need to be handled by the keypad code:</p>
<figure>
 <table>
  <tr><th>Scan code</th><th>Key</th><th>Mapping</th></tr>
  <tr><td>13</td><td>Enter</td><td>Start</td></tr>
  <tr><td>32</td><td>Space</td><td>Select</td></tr>
  <tr><td>37</td><td>Left arrow</td><td>Left</td></tr>
  <tr><td>38</td><td>Up arrow</td><td>Up</td></tr>
  <tr><td>39</td><td>Right arrow</td><td>Right</td></tr>
  <tr><td>40</td><td>Down arrow</td><td>Down</td></tr>
  <tr><td>88</td><td>X</td><td>B</td></tr>
  <tr><td>90</td><td>Z</td><td>A</td></tr>
 </table>
 <figcaption>Table 1: Key-scan codes used by jsGB</figcaption>
</figure>
<p>As stated above, the appropriate bits must be reset when a key is pressed, and set when the key is released. This can be implemented as follows.</p>
<samp>
 <h3>Key.js: Keypress handling</h3>
 <pre>    kdown: <kbd>function</kbd>(e)
    {
    	<kbd>switch</kbd>(e.keyCode)
	{
            <kbd>case</kbd> <var>39</var>: KEY._keys[<var>1</var>] &amp;= <var>0xE</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>37</var>: KEY._keys[<var>1</var>] &amp;= <var>0xD</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>38</var>: KEY._keys[<var>1</var>] &amp;= <var>0xB</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>40</var>: KEY._keys[<var>1</var>] &amp;= <var>0x7</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>90</var>: KEY._keys[<var>0</var>] &amp;= <var>0xE</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>88</var>: KEY._keys[<var>0</var>] &amp;= <var>0xD</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>32</var>: KEY._keys[<var>0</var>] &amp;= <var>0xB</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>13</var>: KEY._keys[<var>0</var>] &amp;= <var>0x7</var>; <kbd>break</kbd>;
	}
    },

    kup</span>: <kbd>function</kbd>(e)
    {
    	<kbd>switch</kbd>(e.keyCode)
	{
            <kbd>case</kbd> <var>39</var>: KEY._keys[<var>1</var>] |= <var>0x1</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>37</var>: KEY._keys[<var>1</var>] |= <var>0x2</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>38</var>: KEY._keys[<var>1</var>] |= <var>0x4</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>40</var>: KEY._keys[<var>1</var>] |= <var>0x8</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>90</var>: KEY._keys[<var>0</var>] |= <var>0x1</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>88</var>: KEY._keys[<var>0</var>] |= <var>0x2</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>32</var>: KEY._keys[<var>0</var>] |= <var>0x4</var>; <kbd>break</kbd>;
            <kbd>case</kbd> <var>13</var>: KEY._keys[<var>0</var>] |= <var>0x8</var>; <kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Testing and next steps</h2>
<p>Figure 1 above shows the result of these additions to the emulator, when running a basic tic-tac-toe game. In this example, the initial screen can be advanced to the credits by pressing the Start key, which is mapped to Enter by this emulator. Another press of the Start key will bring up the game screen, and the game can be played with the player as one side, and the computer as the other; pressing the GameBoy's A key (mapped to Z) will place a cross or circle on behalf of the player.</p>
<p>Right now, the game must be played blind, since there is no indicator of where the player places a mark. The game produces this indicator by using a sprite: a tile which can be placed by the graphics chip above the background, and moved independently. Most games produce their gameplay through use of sprites, so building them into the simulation is an important next step for this series. Next time, I'll be taking a look at the facilities provided by the GameBoy for the rendering of sprites, and how they can be implemented in JavaScript.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Sep 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Integration</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/integration" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Integration" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/integration</id>
 <summary>In the fifth part of the series, the graphics subsystem of the GameBoy emulator is tied to the memory handler, and a rudimentary interface provided for the activation of the emulator. This part includes a working demo of the emulator so far, as will subsequent parts.</summary>
 <category term="Series" />
 <published>Sun, 05 Sep 2010 19:11:40 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#jsgb { display: flex; flex-direction: column; align-items: center; gap: 16px; }
#jsgb_msg { font: 0.8em Inconsolata, monospace; }
#jsgb_controls a { cursor: pointer; }
</style>
<p>
 <em>This is part 5 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>In part 4, the GameBoy's graphics subsystem was explored in detail, and an emulation put together. Without a set of register mappings for the GPU to be dealt with in software, the graphics subsystem cannot be used by the emulator; once these registers have been made available, the emulator is essentially ready for basic use.</p>
<p>With the additions detailed below to add the GPU registers, and a basic interface for the control of the emulator, the result is as follows.</p>
<figure>
 <div id="jsgb">
  <script src="/content/files/jsgb-gpu-ctrl.jsgb.js"></script>
  <div id="jsgb_msg"></div>
  <canvas id="jsgb_screen" width="160" height="144"></canvas>
  <div id="jsgb_controls"><a id="jsgb_reset">Reset</a> | <a id="jsgb_run">Run</a></div>
 </div>
 <figcaption>Figure 1: jsGB implementation with graphics</figcaption>
</figure>
<h2>GPU registers</h2>
<p>The graphics unit of the GameBoy has a series of registers which are mapped into memory, in the I/O space of the <a href="http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory">memory map</a>. In order to get a working emulation with a background image, the following registers will be needed by the GPU (other registers are also available to the GPU, and will be explored in later parts of this series).</p>
<figure>
 <table>
  <tr><th>Address</th><th>Register</th><th>Status</th></tr>
  <tr><td>0xFF40</td><td>LCD and GPU control</td><td>Read/write</td></tr>
  <tr><td>0xFF42</td><td>Scroll-Y</td><td>Read/write</td></tr>
  <tr><td>0xFF43</td><td>Scroll-X</td><td>Read/write</td></tr>
  <tr><td>0xFF44</td><td>Current scan line</td><td>Read only</td></tr>
  <tr><td>0xFF47</td><td>Background palette</td><td>Write only</td></tr>
 </table>
 <figcaption>Table 1: Basic GPU registers</figcaption>
</figure>
<p>The background palette register has previously been explored, and consists of four 2-bit palette entries. The scroll registers and scanline counter are full-byte values; this leaves the LCD control register, which is made up of 8 separate flags controlling the sections of the GPU.</p>
<figure>
 <table>
  <tr><th>Bit</th><th>Function</th><th>When 0</th><th>When 1</th></tr>
  <tr><td>0</td><td>Background: on/off</td><td>Off</td><td>On</td></tr>
  <tr><td>1</td><td>Sprites: on/off</td><td>Off</td><td>On</td></tr>
  <tr><td>2</td><td>Sprites: size (pixels)</td><td>8x8</td><td>8x16</td></tr>
  <tr><td>3</td><td>Background: tile map</td><td>#0</td><td>#1</td></tr>
  <tr><td>4</td><td>Background: tile set</td><td>#0</td><td>#1</td></tr>
  <tr><td>5</td><td>Window: on/off</td><td>Off</td><td>On</td></tr>
  <tr><td>6</td><td>Window: tile map</td><td>#0</td><td>#1</td></tr>
  <tr><td>7</td><td>Display: on/off</td><td>Off</td><td>On</td></tr>
 </table>
 <figcaption>Table 2: GPU control register</figcaption>
</figure>
<p>In the above table, the additional features of the GPU appear: a "window" layer which can appear above the background, and sprite objects which can be moved against the background and window. These additional features will be covered as the need for them arises; in the meantime, the background flags are most important for basic rendering functions. In particular, it can be seen here how the background tile map and tile set can be changed, simply by flipping bits in the register <code>0xFF40</code>.</p>
<h2>Implementation: GPU registers</h2>
<p>Armed with the conceptual GPU register layout, an emulation can be implemented simply by adding handlers for these addresses to the MMU. This can either be done by hard-coding the GPU updates into the MMU, or defining a range of registers wherein the GPU will be called from the MMU, for more specialised handling to be done from there. In the interests of modularity, the latter approach has been taken here.</p>
<samp>
 <h3>MMU.js: Zero-page I/O: GPU</h3>
 <pre>    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// Zero-page</s>
		    <kbd>case</kbd> <var>0xF00</var>:
		        <kbd>if</kbd>(addr &gt;= <var>0xFF80</var>)
			{
			    <kbd>return</kbd> MMU._zram[addr &amp; <var>0x7F</var>];
			}
			<kbd>else</kbd>
			{
			    <s>// I/O control handling</s>
			    <kbd>switch</kbd>(addr &amp; <var>0x00F0</var>)
			    {
			        <s>// GPU (64 registers)</s>
			        <kbd>case</kbd> <var>0x40</var>: <kbd>case</kbd> <var>0x50</var>: <kbd>case</kbd> <var>0x60</var>: <kbd>case</kbd> <var>0x70</var>:
				    <kbd>return</kbd> GPU.rb(addr);
			    }
			    <kbd>return</kbd> <var>0</var>;
			}
		}
	}
    },

    wb: <kbd>function</kbd>(addr, val)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    ...
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    ...
		    <s>// Zero-page</s>
		    <kbd>case</kbd> <var>0xF00</var>:
		        <kbd>if</kbd>(addr &gt;= <var>0xFF80</var>)
			{
			    MMU._zram[addr &amp; <var>0x7F</var>] = val;
			}
			<kbd>else</kbd>
			{
			    <s>// I/O</s>
			    <kbd>switch</kbd>(addr &amp; <var>0x00F0</var>)
			    {
			        <s>// GPU</s>
			        <kbd>case</kbd> <var>0x40</var>: <kbd>case</kbd> <var>0x50</var>: <kbd>case</kbd> <var>0x60</var>: <kbd>case</kbd> <var>0x70</var>:
				    GPU.wb(addr, val);
				    <kbd>break</kbd>;
			    }
			}
			<kbd>break</kbd>;
		}
		<kbd>break</kbd>;
	}
    }</pre>
 <h3>GPU.js: Register handling</h3>
 <pre>    rb: <kbd>function</kbd>(addr)
    {
        <kbd>switch</kbd>(addr)
	{
	    <s>// LCD Control</s>
	    <kbd>case</kbd> <var>0xFF40</var>:
	        <kbd>return</kbd> (GPU._switchbg  ? <var>0x01</var> : <var>0x00</var>) |
		       (GPU._bgmap     ? <var>0x08</var> : <var>0x00</var>) |
		       (GPU._bgtile    ? <var>0x10</var> : <var>0x00</var>) |
		       (GPU._switchlcd ? <var>0x80</var> : <var>0x00</var>);

	    <s>// Scroll Y</s>
	    <kbd>case</kbd> <var>0xFF42</var>:
	        <kbd>return</kbd> GPU._scy;

	    <s>// Scroll X</s>
	    <kbd>case</kbd> <var>0xFF43</var>:
	        <kbd>return</kbd> GPU._scx;

	    <s>// Current scanline</s>
	    <kbd>case</kbd> <var>0xFF44</var>:
	        <kbd>return</kbd> GPU._line;
	}
    },

    wb: <kbd>function</kbd>(addr, val)
    {
        <kbd>switch</kbd>(addr)
	{
	    <s>// LCD Control</s>
	    <kbd>case</kbd> <var>0xFF40</var>:
	        GPU._switchbg  = (val &amp; <var>0x01</var>) ? <var>1</var> : <var>0</var>;
		GPU._bgmap     = (val &amp; <var>0x08</var>) ? <var>1</var> : <var>0</var>;
		GPU._bgtile    = (val &amp; <var>0x10</var>) ? <var>1</var> : <var>0</var>;
		GPU._switchlcd = (val &amp; <var>0x80</var>) ? <var>1</var> : <var>0</var>;
		<kbd>break</kbd>;

	    <s>// Scroll Y</s>
	    <kbd>case</kbd> <var>0xFF42</var>:
	        GPU._scy = val;
		<kbd>break</kbd>;

	    <s>// Scroll X</s>
	    <kbd>case</kbd> <var>0xFF43</var>:
	        GPU._scx = val;
		<kbd>break</kbd>;

	    <s>// Background palette</s>
	    <kbd>case</kbd> <var>0xFF47</var>:
	        <kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>4</var>; i++)
		{
		    <kbd>switch</kbd>((val &gt;&gt; (i * <var>2</var>)) &amp; <var>3</var>)
		    {
		        <kbd>case</kbd> <var>0</var>: GPU._pal[i] = [<var>255</var>,<var>255</var>,<var>255</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>1</var>: GPU._pal[i] = [<var>192</var>,<var>192</var>,<var>192</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>2</var>: GPU._pal[i] = [ <var>96</var>, <var>96</var>, <var>96</var>,<var>255</var>]; <kbd>break</kbd>;
			<kbd>case</kbd> <var>3</var>: GPU._pal[i] = [  <var>0</var>,  <var>0</var>,  <var>0</var>,<var>255</var>]; <kbd>break</kbd>;
		    }
		}
		<kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Running one frame</h2>
<p>At present, the dispatch loop for the emulator's CPU runs forever, without pause. The most basic interface for an emulator allows for the simulation to be reset or paused; in order to allow for this, a known amount of time must be used as the base unit of the emulator interface. There are three possible units of time that can be used for this:</p>
<ul>
 <li><strong>Instruction</strong>: Providing the opportunity to pause after every CPU instruction. This causes a great deal of overhead, since the dispatch function must be called for each step made by the CPU; at 4.19MHz, many steps must be made for an appreciable amount to happen.</li>
 <li><strong>Scanline</strong>: Pausing after the rendering of each line by the GPU. This produces less of an overhead, but the dispatcher must still be called a few thousand times a second; in addition, the emulation can be paused in a state where the canvas display doesn't correspond to the current scanline.</li>
 <li><strong>Frame</strong>: Allowing for the emulation to stop after a whole frame is emulated, rendered and pushed to the canvas. This provides the best compromise of timing accuracy and optimal speed, while ensuring that the emulated canvas is consistent with the GPU state.</li>
</ul>
<p>Since a frame is made of 144 scanlines and a 10-line vertical blank, and each scanline takes 456 clock cycles to run, the length of a frame is 70224 clocks. In conjunction with an emulator-level reset function, which initialises each subsystem at the start of the emulation, the emulator itself can be run, and a rudimentary interface provided.</p>
<samp>
 <h3>index.html: Emulator interface</h3>
 <pre>&lt;canvas id="screen" width="160" height="144"&gt;&lt;/canvas&gt;
&lt;a id="reset"&gt;Reset&lt;/a&gt; | &lt;a id="run"&gt;Run&lt;/a&gt;</pre>
 <h3>jsGB.js: Reset and dispatch</h3>
 <pre>jsGB = {
    reset: <kbd>function</kbd>()
    {
    	GPU.reset();
	MMU.reset();
	Z80.reset();

	MMU.load(<var>'test.gb'</var>);
    },

    frame: <kbd>function</kbd>()
    {
        <kbd>var</kbd> fclk = Z80._clock.t + <var>70224</var>;
	<kbd>do</kbd>
	{
	    Z80._map[MMU.rb(Z80._r.pc++)]();
	    Z80._r.pc &amp;= <var>65535</var>;
	    Z80._clock.m += Z80._r.m;
	    Z80._clock.t += Z80._r.t;
	    GPU.step();
	} <kbd>while</kbd>(Z80._clock.t &lt; fclk);
    },

    _interval: <var>null</var>,

    run: <kbd>function</kbd>()
    {
        <kbd>if</kbd>(!jsGB._interval)
	{
	    jsGB._interval = <kbd>setTimeout</kbd>(jsGB.frame, <var>1</var>);
	    <kbd>document</kbd>.getElementById(<var>'run'</var>).innerHTML = <var>'Pause'</var>;
	}
	<kbd>else</kbd>
	{
	    <kbd>clearInterval</kbd>(jsGB._interval);
	    jsGB._interval = <var>null</var>;
	    <kbd>document</kbd>.getElementById(<var>'run'</var>).innerHTML = <var>'Run'</var>;
	}
    }
};

<kbd>window</kbd>.onload = <kbd>function</kbd>()
{
    <kbd>document</kbd>.getElementById(<var>'reset'</var>).onclick = jsGB.reset;
    <kbd>document</kbd>.getElementById(<var>'run'</var>).onclick = jsGB.run;
    jsGB.reset();
};</pre>
</samp>
<h2>Testing</h2>
<p>Previously shown in Figure 1 is the result of bringing this code together: the emulator is capable of loading and running a graphics-based demo. In this case, the test ROM being loaded is a scrolling test written by <a href="http://www.opusgames.com/">Doug Lanford</a>: the background displayed will scroll when one of the directional keypad buttons is pressed. In this particular case, with the keypad un-emulated, a static background is displayed.</p>
<p>In the next part, this piece of the jigsaw will be put in place: a keypad simulation which can provide the appropriate inputs to the emulated program. I'll also be looking at how the keypad works, and how the inputs are mapped into memory.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Sep 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Graphics</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/graphics" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Graphics" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/graphics</id>
 <summary>The exploration of system emulation in JavaScript continues, with a detailed look at the GameBoy graphics system, and how graphics are rendered by the GameBoy hardware; a simulation of the process is then put in place for use by the wider graphics engine.</summary>
 <category term="Series" />
 <published>Wed, 25 Aug 2010 12:21:45 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This is part 4 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
 </em>
</p>
<p>Previously in this series, the shape of a GameBoy emulator was brought together, and the timings established between the CPU and graphics processor. A canvas has been initialised and is ready for graphics to be drawn by the emulated GameBoy; the GPU emulation now has structure, but is still unable to render graphics to the framebuffer. In order for the emulation to render graphics, the concepts behind GameBoy graphics must be briefly examined.</p>
<h2>Backgrounds</h2>
<p>Just like most consoles of the era, the GameBoy didn't have enough memory to allow for a direct framebuffer to be held in memory. Instead, a tile system is employed: a set of small bitmaps is held in memory, and a map is built using references to these bitmaps. The innate advantage to this system is that one tile can be used repeatedly through the map, simply by using its reference.</p>
<p>The GameBoy's tiled graphics system operates with tiles of 8x8 pixels, and 256 unique tiles can be used in a map; there are two maps of 32x32 tiles that can be held in memory, and one of them can be used for the display at a time. There is space in the GameBoy memory for 384 tiles, so half of them are shared between the maps: one map uses tile numbers from 0 to 255, and the other uses numbers between -128 and 127 for its tiles.</p>
<p>In video memory, the layout of the tile data and maps runs as follows.</p>
<figure>
 <table>
  <tr><th>Region</th><th>Usage</th></tr>
  <tr><td>8000-87FF</td><td>Tile set #1: tiles 0-127</td></tr>
  <tr><td>8800-8FFF</td><td>Tile set #1: tiles 128-255<br>Tile set #0: tiles -1 to -128</td></tr>
  <tr><td>9000-97FF</td><td>Tile set #0: tiles 0-127</td></tr>
  <tr><td>9800-9BFF</td><td>Tile map #0</td></tr>
  <tr><td>9C00-9FFF</td><td>Tile map #1</td></tr>
 </table>
 <figcaption>Table 1: VRAM layout</figcaption>
</figure>
<p>When a background is defined, its map and tile data interact to produce the graphical display:</p>
<figure class="invertable">
 <img src="/content/img/jsgb-gpu-bg-map.png" alt="Background map and tile data">
 <figcaption>Figure 1: Background mapping</figcaption>
</figure>
<p>The background map is, as previously mentioned, 32x32 tiles; this comes to 256 by 256 pixels. The display of the GameBoy is 160x144 pixels, so there's scope for the background to be moved relative to the screeen. The GPU achieves this by defining a point in the background that corresponds to the top-left of the screen: by moving this point between frames, the background is made to scroll on the screen. For this reason, the definition of the top-left corner is held by two GPU registers: Scroll X and Scroll Y.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-gpu-bg-scrl.png" alt="Background scroll registers">
 <figcaption>Figure 2: Background scroll registers</figcaption>
</figure>
<h2>Palettes</h2>
<p>The GameBoy is often described as a monochrome machine, capable of displaying only black and white. This isn't quite true: the GameBoy can also handle light and dark grey, for a total of four colours. Representing one of these four colours in the tile data takes two bits, so each tile in the tile data set is held in (8x8x2) bits, or 16 bytes.</p>
<p>One additional complication for the GameBoy background is that a palette is intersticed between the tile data and the final display: each of the four possible values for a tile pixel can correspond to any of the four colours. This is used mainly to allow easy colour changes for the tile set; if, for example, a set of tiles is held corresponding to the English alphabet, an inverse-video version can be built by changing the palette, instead of taking up another part of the tile set. The four palette entries are all updated at once, by changing the value of the Background Palette GPU register; the colour references used, and the structure of the register, are shown below.</p>
<figure class="invertable">
 <table>
  <tr><th>Value</th><th>Pixel</th><th>Emulated colour</th></tr>
  <tr><td>0</td><td>Off</td><td><code>[255, 255, 255]</code></td></tr>
  <tr><td>1</td><td>33% on</td><td><code>[192, 192, 192]</code></td></tr>
  <tr><td>2</td><td>66% on</td><td><code>[96, 96, 96]</code></td></tr>
  <tr><td>3</td><td>On</td><td><code>[0, 0, 0]</code></td></tr>
 </table>
 <figcaption>Table 2: Colour reference values</figcaption>
 <img src="/content/img/jsgb-gpu-bg-pal.png" alt="Background palette">
 <figcaption>Figure 3: Background palette register</figcaption>
</figure>
<h2>Implementation: tile data</h2>
<p>As stated above, each pixel in the tile data set is represented by two bits: these bits are read by the GPU when the tile is referenced in the map, run through the palette and pushed to screen. The hardware of the GPU is wired such that one whole row of the tile is accessible at the same time, and the pixels are cycled through by running up the bits. The only issue with this is that one row of the tile is two bytes: from this results the slightly convoluted scheme for storage of the bits, where each pixel's low bit is held in one byte, and the high bit in the other byte.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-gpu-bg-tile.png" alt="Tile data bitmap">
 <figcaption>Figure 4: Tile data bitmap structure</figcaption>
</figure>
<p>Since JavaScript isn't ideally suited for manipulating bitmap structures quickly, the most time-efficient way of handling the tile data set is to maintain an internal data set alongside the video memory, with a more expanded view where each pixel's value has been pre-calculated. In order for this to accurately reflect the tile data set, any writes to the video RAM must trigger the function to update the GPU's internal tile data.</p>
<samp>
 <h3>GPU.js: Internal tile data</h3>
 <pre>    _tileset: [],

    reset: <kbd>function</kbd>()
    {
        <s>// In addition to previous reset code:</s>
	GPU._tileset = [];
	<kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>384</var>; i++)
	{
	    GPU._tileset[i] = [];
	    <kbd>for</kbd>(<kbd>var</kbd> j = <var>0</var>; j &lt; <var>8</var>; j++)
	    {
	        GPU._tileset[i][j] = [<var>0</var>,<var>0</var>,<var>0</var>,<var>0</var>,<var>0</var>,<var>0</var>,<var>0</var>,<var>0</var>];
	    }
	}
    },

    <s>// Takes a value written to VRAM, and updates the
    // internal tile data set</s>
    updatetile: <kbd>function</kbd>(addr, val)
    {
        <s>// Get the "base address" for this tile row</s>
	addr &amp;= <var>0x1FFE</var>;

	<s>// Work out which tile and row was updated</s>
	<kbd>var</kbd> tile = (addr &gt;&gt; <var>4</var>) &amp; <var>511</var>;
	<kbd>var</kbd> y = (addr &gt;&gt; <var>1</var>) &amp; <var>7</var>;

	<kbd>var</kbd> sx;
	<kbd>for</kbd>(<kbd>var</kbd> x = <var>0</var>; x &lt; <var>8</var>; x++)
	{
	    <s>// Find bit index for this pixel</s>
	    sx = <var>1</var> &lt;&lt; (<var>7</var>-x);

	    <s>// Update tile set</s>
	    GPU._tileset[tile][y][x] =
	        ((GPU._vram[addr] &amp; sx)   ? <var>1</var> : <var>0</var>) +
	        ((GPU._vram[addr+1] &amp; sx) ? <var>2</var> : <var>0</var>);
	}
    }</pre>
 <h3>MMU.js: Tile update trigger</h3>
 <pre>    wb: <kbd>function</kbd>(addr, val)
    {
        <kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
            <s>// Only the VRAM case is shown:</s>
	    <kbd>case</kbd> <var>0x8000</var>:
	    <kbd>case</kbd> <var>0x9000</var>:
		GPU._vram[addr &amp; <var>0x1FFF</var>] = val;
		GPU.updatetile(addr, val);
		<kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Implementation: Scan rendering</h2>
<p>With these pieces in place, it's possible to begin rendering the GameBoy screen. Since this is being done on a line-by-line basis, the <code>renderscan</code> function referred to in Part 3 must, before it renders a scanline, work out where it is on the screen. This involves calculating the X and Y coordinates of the position in the background map, using the scroll registers and the current scanline counter. Once this has been determined, the scan renderer can advance through each tile in that row of the map, pulling in new tile data as it encounters each tile.</p>
<samp>
 <h3>GPU.js: Scan rendering</h3>
 <pre>    renderscan: <kbd>function</kbd>()
    {
	<s>// VRAM offset for the tile map</s>
	<kbd>var</kbd> mapoffs = GPU._bgmap ? <var>0x1C00</var> : <var>0x1800</var>;

	<s>// Which line of tiles to use in the map</s>
	mapoffs += ((GPU._line + GPU._scy) &amp; <var>255</var>) &gt;&gt; <var>3</var>;
	
	<s>// Which tile to start with in the map line</s>
	<kbd>var</kbd> lineoffs = (GPU._scx &gt;&gt; <var>3</var>);

	<s>// Which line of pixels to use in the tiles</s>
	<kbd>var</kbd> y = (GPU._line + GPU._scy) &amp; <var>7</var>;

	<s>// Where in the tileline to start</s>
	<kbd>var</kbd> x = GPU._scx &amp; <var>7</var>;

        <s>// Where to render on the canvas</s>
	<kbd>var</kbd> canvasoffs = GPU._line * <var>160</var> * <var>4</var>;

	<s>// Read tile index from the background map</s>
	<kbd>var</kbd> colour;
	<kbd>var</kbd> tile = GPU._vram[mapoffs + lineoffs];

	<s>// If the tile data set in use is #1, the
	// indices are signed; calculate a real tile offset</s>
	<kbd>if</kbd>(GPU._bgtile == <var>1</var> &amp;&amp; tile &lt; <var>128</var>) tile += <var>256</var>;

	<kbd>for</kbd>(<kbd>var</kbd> i = <var>0</var>; i &lt; <var>160</var>; i++)
	{
	    <s>// Re-map the tile pixel through the palette</s>
	    colour = GPU._pal[GPU._tileset[tile][y][x]];

	    <s>// Plot the pixel to canvas</s>
	    GPU._scrn.data[canvasoffs+<var>0</var>] = colour[<var>0</var>];
	    GPU._scrn.data[canvasoffs+<var>1</var>] = colour[<var>1</var>];
	    GPU._scrn.data[canvasoffs+<var>2</var>] = colour[<var>2</var>];
	    GPU._scrn.data[canvasoffs+<var>3</var>] = colour[<var>3</var>];
	    canvasoffs += <var>4</var>;

	    <s>// When this tile ends, read another</s>
	    x++;
	    <kbd>if</kbd>(x == <var>8</var>)
	    {
		x = <var>0</var>;
		lineoffs = (lineoffs + <var>1</var>) &amp; <var>31</var>;
		tile = GPU._vram[mapoffs + lineoffs];
		<kbd>if</kbd>(GPU._bgtile == <var>1</var> &amp;&amp; tile &lt; <var>128</var>) tile += <var>256</var>;
	    }
	}
    }</pre>
</samp>
<h2>Next steps: Output</h2>
<p>With a CPU, memory handling and a graphics subsystem, the emulator is nearly capable of producing output. In part 5, I'll be looking at what's required to get the system from a disparate set of module files to a coherent whole, capable of loading and running a simple ROM file: tying the graphics registers to the MMU, and a simple interface to control the running of the emulation.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Aug 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: GPU Timings</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/gpu-timing" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: GPU Timings" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/gpu-timing</id>
 <summary>In the third part of a series regarding system emulation in JavaScript, the GameBoy as an example of a raster graphics system is looked at, and the timings established for passing of control between CPU and graphics. Also examined is the issue of where the emulated graphics code will be rendering its output, and the HTML5 canvas is introduced as a solution.</summary>
 <category term="Series" />
 <published>Sat, 14 Aug 2010 22:14:31 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This is part 3 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
  The emulator described in this series is available in source form: <a href="https://github.com/Two9A/jsGB">https://github.com/Two9A/jsGB</a>
 </em>
</p>
<p>In the previous parts of this series, a structure for a GameBoy emulator was laid out, and brought to the point where a game ROM could be loaded, and stepped through by the emulated CPU. With the emulated processor attached to a memory mapping structure, it's now possible to attach peripherals to the system. One of the primary peripherals used by the GameBoy, and by any games console, is the graphics processor (GPU): it's the primary method of output for the console, and much of the processor's work goes on generating graphics for the GPU.</p>
<h2>Emulating the screen</h2>
<p>Nintendo's internal name for the GameBoy is "Dot Matrix Game"; its display is a pixel LCD of dimensions 160x144. If each pixel in the LCD is treated as a pixel in a HTML5 <code>&lt;canvas&gt;</code>, a direct mapping can be made to a canvas of width 160 and height 144. In order to directly address each pixel in the LCD, the contents of the canvas can be manipulated as a "framebuffer": a single block of memory containing the entirety of the canvas, as a series of 4-byte RGBA values.</p>
<samp>
 <h3>index.html: Canvas tag</h3>
 <pre>&lt;canvas id="screen" width="160" height="144"&gt;&lt;/canvas&gt;</pre>
 <h3>GPU.js: Canvas initialisation</h3>
 <pre>GPU = {
    _canvas: {},
    _scrn: {},

    reset: <kbd>function</kbd>()
    {
        <kbd>var</kbd> c = document.getElementById(<var>'screen'</var>);
	<kbd>if</kbd>(c &amp;&amp; c.getContext)
	{
	    GPU._canvas = c.getContext(<var>'2d'</var>);
	    <kbd>if</kbd>(GPU._canvas)
	    {
		<kbd>if</kbd>(GPU._canvas.createImageData)
		    GPU._scrn = GPU._canvas.createImageData(<var>160</var>, <var>144</var>);

		<kbd>else if</kbd>(GPU._canvas.getImageData)
		    GPU._scrn = GPU._canvas.getImageData(<var>0</var>,<var>0</var>, <var>160</var>,<var>144</var>);

		<kbd>else</kbd>
		    GPU._scrn = {
		        <var>'width'</var>: <var>160</var>,
			<var>'height'</var>: <var>144</var>,
			<var>'data'</var>: <kbd>new</kbd> Array(<var>160</var>*<var>144</var>*<var>4</var>)
		    };

		<s>// Initialise canvas to white</s>
		<kbd>for</kbd>(<kbd>var</kbd> i=<var>0</var>; i&lt;<var>160</var>*<var>144</var>*<var>4</var>; i++)
		    GPU._scrn.data[i] = <var>255</var>;

		GPU._canvas.putImageData(GPU._scrn, <var>0</var>, <var>0</var>);
	    }
	}
    }
}</pre>
</samp>
<p>Once a block of memory has been allocated for the screen data, an individual pixel's colour can be set by writing RGBA components to the four values at that pixel position in the block; the pixel position can be determined by the formula <code>y * 160 + x</code>.</p>
<h2>Raster graphics</h2>
<p>With a canvas in place to receive the graphic output of the GameBoy, the next step is to emulate the production of graphics. The original GameBoy hardware simulates a cathode-ray tube (CRT) in its timings: in a CRT, the screen is scanned in rows by an electron beam, and the scanning process returns to the top of the screen after the end of scanning.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-gpu-blank.png" alt="Scanlines and blanking periods">
 <figcaption>Figure 1: Scanlines and blanking periods</figcaption>
</figure>
<p>As can be seen above, a CRT requires more time to draw a scanline than simply running over the pixels in question: a "horizontal blanking" period is needed, for the beam to move from the end of one line to the start of the next. Similarly, the end of each frame means a "vertical blanking" period, while the beam travels back to the top-left corner. Since the beam has to move further in vertical blanking, this time period is commonly much longer than the horizontal blanking time.</p>
<p>In the same way, a GameBoy display exhibits horizontal and vertical blanking periods. In addition, time spent within the scanline itself is separated into two parts: the GPU flips between accessing video memory, and accessing sprite attribute memory, while it draws the scanline. For the purpose of this emulation, these two parts are distinct, and follow each other. The following table states how long the GPU stays in each period, in terms of the CPU's T-clock which runs at 4194304 Hz.</p>
<figure>
 <table>
  <tr><th>Period</th><th>GPU mode number</th><th>Time spent (clocks)</th></tr>
  <tr><td>Scanline (accessing OAM)</td><td>2</td><td>80</td></tr>
  <tr><td>Scanline (accessing VRAM)</td><td>3</td><td>172</td></tr>
  <tr><td>Horizontal blank</td><td>0</td><td>204</td></tr>
  <tr><td>One line (scan and blank)</td><td></td><td>456</td></tr>
  <tr><td>Vertical blank</td><td>1</td><td>4560 (10 lines)</td></tr>
  <tr><td>Full frame (scans and vblank)</td><td></td><td>70224</td></tr>
 </table>
 <figcaption>Table 1: GPU frame timings</figcaption>
</figure>
<p>In order to maintain these timings relative to the emulated CPU, a timing update function must exist, which gets called after the execution of every instruction. This can be done from an expanded version of the CPU dispatch process, covered in part 1.</p>
<samp>
 <h3>Z80.js: Dispatcher</h3>
 <pre><kbd>while</kbd>(<var>true</var>)
{
    Z80._map[MMU.rb(Z80._r.pc++)]();
    Z80._r.pc &amp;= <var>65535</var>;
    Z80._clock.m += Z80._r.m;
    Z80._clock.t += Z80._r.t;

    GPU.step();
}</pre>
 <h3>GPU.js: Clock step</h3>
 <pre>    _mode: <var>0</var>,
    _modeclock: <var>0</var>,
    _line: <var>0</var>,

    step: <kbd>function</kbd>()
    {
        GPU._modeclock += Z80._r.t;

	<kbd>switch</kbd>(GPU._mode)
	{
	    <s>// OAM read mode, scanline active</s>
	    <kbd>case</kbd> <var>2</var>:
	        <kbd>if</kbd>(GPU._modeclock &gt;= <var>80</var>)
		{
		    <s>// Enter scanline mode 3</s>
		    GPU._modeclock = <var>0</var>;
		    GPU._mode = <var>3</var>;
		}
		<kbd>break</kbd>;

	    <s>// VRAM read mode, scanline active
	    // Treat end of mode 3 as end of scanline</s>
	    <kbd>case</kbd> <var>3</var>:
	        <kbd>if</kbd>(GPU._modeclock &gt;= <var>172</var>)
		{
		    <s>// Enter hblank</s>
		    GPU._modeclock = <var>0</var>;
		    GPU._mode = <var>0</var>;

		    <s>// Write a scanline to the framebuffer</s>
		    GPU.renderscan();
		}
		<kbd>break</kbd>;

	    <s>// Hblank
	    // After the last hblank, push the screen data to canvas</s>
	    <kbd>case</kbd> <var>0</var>:
	        <kbd>if</kbd>(GPU._modeclock &gt;= <var>204</var>)
		{
		    GPU._modeclock = <var>0</var>;
		    GPU._line++;

		    <kbd>if</kbd>(GPU._line == <var>143</var>)
		    {
		        <s>// Enter vblank</s>
			GPU._mode = <var>1</var>;
			GPU._canvas.putImageData(GPU._scrn, <var>0</var>, <var>0</var>);
		    }
		    <kbd>else</kbd>
		    {
		    	GPU._mode = <var>2</var>;
		    }
		}
		<kbd>break</kbd>;

	    <s>// Vblank (10 lines)</s>
	    <kbd>case</kbd> <var>1</var>:
	        <kbd>if</kbd>(GPU._modeclock &gt;= <var>456</var>)
		{
		    GPU._modeclock = <var>0</var>;
		    GPU._line++;

		    <kbd>if</kbd>(GPU._line &gt; <var>153</var>)
		    {
		        <s>// Restart scanning modes</s>
			GPU._mode = <var>2</var>;
			GPU._line = <var>0</var>;
		    }
		}
		<kbd>break</kbd>;
	}
    }</pre>
</samp>
<h2>Next time: backgrounds and palettes</h2>
<p>In the above code, the timings for the GPU are established, but the work of the GPU isn't yet in place: <code>renderscan</code> is where the work happens. In the next part of this series, the concepts behind the GameBoy's background graphics system will be looked at, and code will be put inside the rendering function to emulate them.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Aug 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: Memory</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/memory" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: Memory" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/memory</id>
 <summary>Continuing a series examining system emulation in JavaScript, this article examines how the GameBoy memories are mapped onto the CPU&#039;s address bus, and how such a mapping can be emulated. Also covered is the dynamic loading of program ROM images after initialisation, through asynchronous file requests.</summary>
 <category term="Series" />
 <published>Mon, 02 Aug 2010 12:03:45 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This is part 2 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
  The emulator described in this series is available in source form: <a href="https://github.com/Two9A/jsGB">https://github.com/Two9A/jsGB</a>
 </em>
</p>
<p>In the previous part of this series, the computer was introduced as a processing unit, which fetches its instructions from memory. In almost every case, a computer's memory is not a simple contiguous region; the GameBoy is no exception in this regard. Since the GameBoy CPU can access 65,536 individual locations on its address bus, a "memory map" can be drawn of all the regions where the CPU has access.</p>
<figure class="invertable">
 <img src="/content/img/jsgb-mmu-map.png" alt="GameBoy memory map">
 <figcaption>Figure 1: Memory map of the GameBoy address bus</figcaption>
</figure>
<p>A more detailed look at the memory regions is as follows:</p>
<ul>
 <li><strong>[0000-3FFF] Cartridge ROM, bank 0</strong>: The first 16,384 bytes of the cartridge program are always available at this point in the memory map. Special circumstances apply:
  <ul>
   <li><strong>[0000-00FF] BIOS</strong>: When the CPU starts up, PC starts at <code>0000h</code>, which is the start of the 256-byte GameBoy BIOS code. Once the BIOS has run, it is removed from the memory map, and this area of the cartridge rom becomes addressable.</li>
   <li><strong>[0100-014F] Cartridge header</strong>: This section of the cartridge contains data about its name and manufacturer, and must be written in a specific format.</li>
  </ul>
 </li>
 <li><strong>[4000-7FFF] Cartridge ROM, other banks</strong>: Any subsequent 16k "banks" of the cartridge program can be made available to the CPU here, one by one; a chip on the cartridge is generally used to switch between banks, and make a particular area accessible. The smallest programs are 32k, which means that no bank-selection chip is required.</li>
 <li><strong>[8000-9FFF] Graphics RAM</strong>: Data required for the backgrounds and sprites used by the graphics subsystem is held here, and can be changed by the cartridge program. This region will be examined in further detail in part 3 of this series.</li>
 <li><strong>[A000-BFFF] Cartridge (External) RAM</strong>: There is a small amount of writeable memory available in the GameBoy; if a game is produced that requires more RAM than is available in the hardware, additional 8k chunks of RAM can be made addressable here.</li>
 <li><strong>[C000-DFFF] Working RAM</strong>: The GameBoy's internal 8k of RAM, which can be read from or written to by the CPU.</li>
 <li><strong>[E000-FDFF] Working RAM (shadow)</strong>: Due to the wiring of the GameBoy hardware, an exact copy of the working RAM is available 8k higher in the memory map. This copy is available up until the last 512 bytes of the map, where other areas are brought into access.</li>
 <li><strong>[FE00-FE9F] Graphics: sprite information</strong>: Data about the sprites rendered by the graphics chip are held here, including the sprites' positions and attributes.</li>
 <li><strong>[FF00-FF7F] Memory-mapped I/O</strong>: Each of the GameBoy's subsystems (graphics, sound, etc.) has control values, to allow programs to create effects and use the hardware. These values are available to the CPU directly on the address bus, in this area.</li>
 <li><strong>[FF80-FFFF] Zero-page RAM</strong>: A high-speed area of 128 bytes of RAM is available at the top of memory. Oddly, though this is "page" 255 of the memory, it is referred to as page zero, since most of the interaction between the program and the GameBoy hardware occurs through use of this page of memory.</li>
</ul>
<h2>Interfacing to the CPU</h2>
<p>In order for the emulated CPU to access these regions separately, each must be handled as a special case in the memory management unit. This part of the code was alluded to in the previous part, and a basic interface described for the MMU object; the fleshing out of the interface can be as simple as a <code>switch</code> statement.</p>
<samp>
 <h3>MMU.js: Mapped read</h3>
 <pre>MMU = {
    <s>// Flag indicating BIOS is mapped in
    // BIOS is unmapped with the first instruction above 0x00FF</s>
    _inbios: <var>1</var>,

    <s>// Memory regions (initialised at reset time)</s>
    _bios: [],
    _rom: [],
    _wram: [],
    _eram: [],
    _zram: [],

    <s>// Read a byte from memory</s>
    rb: <kbd>function</kbd>(addr)
    {
	<kbd>switch</kbd>(addr &amp; <var>0xF000</var>)
	{
	    <s>// BIOS (256b)/ROM0</s>
	    <kbd>case</kbd> <var>0x0000</var>:
	        <kbd>if</kbd>(MMU._inbios)
		{
		    <kbd>if</kbd>(addr &lt; <var>0x0100</var>)
		        <kbd>return</kbd> MMU._bios[addr];
		    <kbd>else if</kbd>(Z80._r.pc == <var>0x0100</var>)
		        MMU._inbios = <var>0</var>;
		}

		<kbd>return</kbd> MMU._rom[addr];

	    <s>// ROM0</s>
	    <kbd>case</kbd> <var>0x1000</var>:
	    <kbd>case</kbd> <var>0x2000</var>:
	    <kbd>case</kbd> <var>0x3000</var>:
	        <kbd>return</kbd> MMU._rom[addr];

	    <s>// ROM1 (unbanked) (16k)</s>
	    <kbd>case</kbd> <var>0x4000</var>:
	    <kbd>case</kbd> <var>0x5000</var>:
	    <kbd>case</kbd> <var>0x6000</var>:
	    <kbd>case</kbd> <var>0x7000</var>:
	        <kbd>return</kbd> MMU._rom[addr];

	    <s>// Graphics: VRAM (8k)</s>
	    <kbd>case</kbd> <var>0x8000</var>:
	    <kbd>case</kbd> <var>0x9000</var>:
	        <kbd>return</kbd> GPU._vram[addr &amp; <var>0x1FFF</var>];

	    <s>// External RAM (8k)</s>
	    <kbd>case</kbd> <var>0xA000</var>:
	    <kbd>case</kbd> <var>0xB000</var>:
	        <kbd>return</kbd> MMU._eram[addr &amp; <var>0x1FFF</var>];

	    <s>// Working RAM (8k)</s>
	    <kbd>case</kbd> <var>0xC000</var>:
	    <kbd>case</kbd> <var>0xD000</var>:
	        <kbd>return</kbd> MMU._wram[addr &amp; <var>0x1FFF</var>];

	    <s>// Working RAM shadow</s>
	    <kbd>case</kbd> <var>0xE000</var>:
	        <kbd>return</kbd> MMU._wram[addr &amp; <var>0x1FFF</var>];

	    <s>// Working RAM shadow, I/O, Zero-page RAM</s>
	    <kbd>case</kbd> <var>0xF000</var>:
	        <kbd>switch</kbd>(addr &amp; <var>0x0F00</var>)
		{
		    <s>// Working RAM shadow</s>
		    <kbd>case</kbd> <var>0x000</var>: <kbd>case</kbd> <var>0x100</var>: <kbd>case</kbd> <var>0x200</var>: <kbd>case</kbd> <var>0x300</var>:
		    <kbd>case</kbd> <var>0x400</var>: <kbd>case</kbd> <var>0x500</var>: <kbd>case</kbd> <var>0x600</var>: <kbd>case</kbd> <var>0x700</var>:
		    <kbd>case</kbd> <var>0x800</var>: <kbd>case</kbd> <var>0x900</var>: <kbd>case</kbd> <var>0xA00:</var> <kbd>case</kbd> <var>0xB00</var>:
		    <kbd>case</kbd> <var>0xC00</var>: <kbd>case</kbd> <var>0xD00</var>:
		        <kbd>return</kbd> MMU._wram[addr &amp; <var>0x1FFF</var>];

		    <s>// Graphics: object attribute memory
		    // OAM is 160 bytes, remaining bytes read as 0</s>
		    <kbd>case</kbd> <var>0xE00</var>:
		        <kbd>if</kbd>(addr &lt; <var>0xFEA0</var>)
			    <kbd>return</kbd> GPU._oam[addr &amp; <var>0xFF</var>];
			<kbd>else</kbd>
			    <kbd>return</kbd> <var>0</var>;

		    <s>// Zero-page</s>
		    <kbd>case</kbd> <var>0xF00</var>:
		        <kbd>if</kbd>(addr &gt;= <var>0xFF80</var>)
			{
			    <kbd>return</kbd> MMU._zram[addr &amp; <var>0x7F</var>];
			}
			<kbd>else</kbd>
			{
			    <s>// I/O control handling
			    // Currently unhandled</s>
			    <kbd>return</kbd> <var>0</var>;
			}
		}
	}
    },

    <s>Read a 16-bit word</s>
    rw: <kbd>function</kbd>(addr)
    {
        <kbd>return</kbd> MMU.rb(addr) + (MMU.rb(addr+<var>1</var>) &lt;&lt; <var>8</var>);
    }
};</pre>
</samp>
<p>In the above section of code, it should be noted that the region of memory between <code>0xFF00</code> and <code>0xFF7F</code> is unhandled; these locations are used as memory-mapped I/O for the various chips that provide I/O, and will be defined as these systems are covered in later parts.</p>
<p>Writing a byte is handled in a very similar manner; each operation is reversed, and values are written to the various regions of memory instead of returned from the function. For this reason, it is not necessary to provide a full extrapolation of the <code>wb</code> function here.
<h2>Loading a ROM</h2>
<p>Just as a CPU emulation is useless without its supporting elements of memory access, graphics and so on, being able to read a program from memory is useless without a program loaded. There are two main ways to pull a program into an emulator: hard-code it into the emulator's source code, or allow for loading of a ROM file from a certain location. The obvious disadvantage of hard-coding the program is that it's fixed, and cannot easily be changed.</p>
<p>In the case of this JavaScript emulator, the GameBoy BIOS is hard-coded into the MMU, because it isn't liable to change; the program file is, however, loaded from the server asynchronously, after the emulator has initialised. This can be done through XMLHTTP, using a binary file reader such as <a href="http://nagoon97.wordpress.com/2008/04/06/reading-binary-files-using-ajax/">Andy Na's BinFileReader</a>; the result of this is a string containing the ROM file.</p>
<samp>
 <h3>MMU.js: ROM file loading</h3>
 <pre>MMU.load = <kbd>function</kbd>(file)
{
    <kbd>var</kbd> b = <kbd>new</kbd> BinFileReader(file);
    MMU._rom = b.readString(b.getFileSize(), <var>0</var>);
};</pre>
</samp>
<p>Since the ROM file is held as a string, instead of an array of numbers, the <code>rb</code> and <code>wb</code> functions must be changed to index a string:</p>
<samp>
 <h3>MMU.js: ROM file indexing</h3>
 <pre>	    <kbd>case</kbd> <var>0x1000</var>:
	    <kbd>case</kbd> <var>0x2000</var>:
	    <kbd>case</kbd> <var>0x3000</var>:
	        <kbd>return</kbd> MMU._rom.charCodeAt(addr);
 </pre>
</samp>
<h2>Next steps</h2>
<p>With a CPU and MMU in place, it is possible to watch a program being executed, step by step: an emulation can be achieved, and produce the expected values in the right registers. What's missing is a sense of what that means for graphical output. In the next part of this series, the issue of graphics will be looked at, including how the GameBoy structures its graphic output, and how to render graphics onto the screen.</p>
<p>As with part 1, the source for this article is available at: <a href="http://imrannazar.com/content/files/jsgb.mmu.js">http://imrannazar.com/content/files/jsgb.mmu.js</a>.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Aug 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">GameBoy Emulation in JavaScript: The CPU</title>
 <link href="https://imrannazar.com/series/gameboy-emulation-in-javascript/cpu" rel="alternate" type="text/html" title="GameBoy Emulation in JavaScript: The CPU" />
 <id>https://imrannazar.com/series/gameboy-emulation-in-javascript/cpu</id>
 <summary>In the first of this series of articles, I&#039;ll look at how a CPU can be emulated through JS, and start building an emulation core for the GameBoy console.</summary>
 <category term="Series" />
 <published>Thu, 22 Jul 2010 18:11:40 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
 <em>This is part 1 of an article series on emulation development in JavaScript; ten parts are currently available, and others are expected to follow.
  <ul>
   <li><a href="/series/gameboy-emulation-in-javascript/cpu">Part 1: The CPU</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory">Part 2: Memory</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/gpu-timing">Part 3: GPU Timings</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/graphics">Part 4: Graphics</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/integration">Part 5: Integration</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/input">Part 6: Input</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/sprites">Part 7: Sprites</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/interrupts">Part 8: Interrupts</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/memory-banks">Part 9: Memory Banking</a></li>
   <li><a href="/series/gameboy-emulation-in-javascript/timers">Part 10: Timers</a></li>
  </ul>
  The emulator described in this series is available in source form: <a href="https://github.com/Two9A/jsGB">https://github.com/Two9A/jsGB</a>
 </em>
</p>
<p>It's often stated that JavaScript is a special-purpose language, designed for use by web sites to enable dynamic interaction. However, JavaScript is a full object-oriented programming language, and is used in arenas besides the Web: the Widgets available for recent versions of Windows and Apple's Mac OS are implemented in JavaScript, as is the GUI for the Mozilla application suite.</p>
<p>With the recent introduction of the <code>&lt;canvas&gt;</code> tag to HTML, the question arises as to whether a JavaScript program is capable of emulating a system, much like desktop applications are available to emulate the Commodore 64, GameBoy Advance and other gaming consoles. The simplest way of checking whether this is viable is, of course, to write such an emulator in JavaScript.</p>
<p>This article sets out to implement the basis for a GameBoy emulation, by laying the groundwork for emulating each part of the physical machine. The starting point is the CPU.</p>
<h2>The model</h2>
<p>The traditional model of a computer is a processing unit, which gets told what to do by a program of instructions; the program might be accessed with its own special memory, or it might be sitting in the same area as normal memory, depending on the computer. Each instruction takes a short amount of time to run, and they're all run one by one. From the CPU's perspective, a loop starts up as soon as the computer is turned on, to fetch an instruction from memory, work out what it says, and execute it.</p>
<p>In order to keep track of where the CPU is within the program, a number is held by the CPU called the Program Counter (PC). After an instruction is fetched from memory, the PC is advanced by however many bytes make up the instruction.</p>
<figure class="invertable">
 <img src='/content/img/jsgb-cpu-fetchloop.png' alt='Fetch-decode-execute loop'>
 <figcaption>Figure 1: The fetch-decode-execute loop</figcaption>
</figure>
<p>The CPU in the original GameBoy is a modified Zilog Z80, so the following things are pertinent:</p>
<ul>
 <li>The Z80 is an 8-bit chip, so all the internal workings operate on one byte at a time;</li>
 <li>The memory interface can address up to 65,536 bytes (a 16-bit address bus);</li>
 <li>Programs are accessed through the same address bus as normal memory;</li>
 <li>An instruction can be anywhere between one and three bytes.</li>
</ul>
<p>In addition to the PC, other numbers are held inside the CPU that can be used for calculation, and they're referred to as registers: A, B, C, D, E, H, and L. Each of them is one byte, so each one can hold a value from 0 to 255. Most of the instructions in the Z80 are used to handle values in these registers: loading a value from memory into a register, adding or subtracting values, and so forth.</p>
<p>If there are 256 possible values in the first byte of an instruction, that makes for 256 possible instructions in the basic table. That table is detailed in the <a href="/Gameboy-Z80-Opcode-Map">Gameboy Z80 opcode map</a> released on this site. Each of these can be simulated by a JavaScript function, that operates on an internal model of the registers, and produces effects on an internal model of the memory interface.</p>
<p>There are other registers in the Z80, that deal with holding status: the flags register (F), whose operation is discussed below; and the stack pointer (SP) which is used alongside the PUSH and POP instructions for basic LIFO handling of values. The basic model of the Z80 emulation would therefore require the following components:</p>
<ul>
 <li>An internal state:
  <ul>
   <li>A structure for retaining the current state of the registers;</li>
   <li>The amount of time used to execute the last instruction;</li>
   <li>The amount of time that the CPU has run in total;</li>
  </ul>
 </li>
 <li>Functions to simulate each instruction;</li>
 <li>A table mapping said functions onto the opcode map;</li>
 <li>A known interface to talk to the simulated memory.</li>
</ul>
<p>The internal state can be held as follows:</p>
<samp>
 <h3>Z80.js: Internal state values</h3>
 <pre>Z80 = {
    <s>// Time clock: The Z80 holds two types of clock (m and t)</s>
    _clock: {m:<var>0</var>, t:<var>0</var>},

    <s>// Register set</s>
    _r: {
        a:<var>0</var>, b:<var>0</var>, c:<var>0</var>, d:<var>0</var>, e:<var>0</var>, h:<var>0</var>, l:<var>0</var>, f:<var>0</var>,    <s>// 8-bit registers</s>
        pc:<var>0</var>, sp:<var>0</var>,                                <s>// 16-bit registers</s>
        m:<var>0</var>, t:<var>0</var>                                   <s>// Clock for last instr</s>
    }
};</pre>
</samp>
<p>The flags register (F) is important to the functioning of the processor: it automatically calculates certain bits, or flags, based on the result of the last operation. There are four flags in the Gameboy Z80:</p>
<ul>
 <li>Zero (0x80): Set if the last operation produced a result of 0;</li>
 <li>Operation (0x40): Set if the last operation was a subtraction;</li>
 <li>Half-carry (0x20): Set if, in the result of the last operation, the lower half of the byte overflowed past 15;</li>
 <li>Carry (0x10): Set if the last operation produced a result over 255 (for additions) or under 0 (for subtractions).</li>
</ul>
<p>Since the basic calculation registers are 8-bits, the carry flag allows for the software to work out what happened to a value if the result of a calculation overflowed the register. With these flag handling issues in mind, a few examples of instruction simulations are shown below. These examples are simplified, and don't calculate the half-carry flag.</p>
<samp>
 <h3>Z80.js: Instruction simulations</h3>
 <pre>Z80 = {
    <s>// Internal state</s>
    _clock: {m:<var>0</var>, t:<var>0</var>},
    _r: {a:<var>0</var>, b:<var>0</var>, c:<var>0</var>, d:<var>0</var>, e:<var>0</var>, h:<var>0</var>, l:<var>0</var>, f:<var>0</var>, pc:<var>0</var>, sp:<var>0</var>, m:<var>0</var>, t:<var>0</var>},

    <s>// Add E to A, leaving result in A (ADD A, E)</s>
    ADDr_e: <kbd>function</kbd>() {
        Z80._r.a += Z80._r.e;                      <s>// Perform addition</s>
        Z80._r.f = <var>0</var>;                              <s>// Clear flags</s>
        <kbd>if</kbd>(!(Z80._r.a &amp; <var>255</var>)) Z80._r.f |= <var>0x80</var>;    <s>// Check for zero</s>
        <kbd>if</kbd>(Z80._r.a &gt; <var>255</var>) Z80._r.f |= <var>0x10</var>;       <s>// Check for carry</s>
        Z80._r.a &amp;= <var>255</var>;                           <s>// Mask to 8-bits</s>
        Z80._r.m = <var>1</var>; Z80._r.t = <var>4</var>;                <s>// 1 M-time taken</s>
    }

    <s>// Compare B to A, setting flags (CP A, B)</s>
    CPr_b: <kbd>function</kbd>() {
        <kbd>var</kbd> i = Z80._r.a;                          <s>// Temp copy of A</s>
        i -= Z80._r.b;                             <s>// Subtract B</s>
        Z80._r.f |= <var>0x40</var>;                          <s>// Set subtraction flag</s>
        <kbd>if</kbd>(!(i &amp; <var>255</var>)) Z80._r.f |= <var>0x80</var>;       <s>    // Check for zero</s>
        <kbd>if</kbd>(i &lt; <var>0</var>) Z80._r.f |= <var>0x10</var>;             <s>   // Check for underflow</s>
        Z80._r.m = <var>1</var>; Z80._r.t = <var>4</var>;                <s>// 1 M-time taken</s>
    }

    <s>// No-operation (NOP)</s>
    NOP: <kbd>function</kbd>() {
        Z80._r.m = <var>1</var>; Z80._r.t = <var>4</var>;                <s>// 1 M-time taken</s>
    }
};</pre>
</samp>
<h2>Memory interfacing</h2>
<p>A processor that can manipulate registers within itself is all well and good, but it must be able to put results into memory to be useful. In the same way, the above CPU emulation requires an interface to emulated memory; this can be provided by a memory management unit (MMU). Since the Gameboy itself doesn't contain a complicated MMU, the emulated unit can be quite simple.</p>
<p>At this point, the CPU only needs to know that an interface is present; the details of how the Gameboy maps banks of memory and hardware onto the address bus are inconsequential to the processor's operation. Four operations are required by the CPU:</p>
<samp>
 <h3>MMU.js: Memory interface</h3>
 <pre>MMU = {
    rb: <kbd>function</kbd>(addr) { <s>/* Read 8-bit byte from a given address */</s> },
    rw: <kbd>function</kbd>(addr) { <s>/* Read 16-bit word from a given address */</s> },

    wb: <kbd>function</kbd>(addr, val) { <s>/* Write 8-bit byte to a given address */</s> },
    ww: <kbd>function</kbd>(addr, val) { <s>/* Write 16-bit word to a given address */</s> }
};</pre>
</samp>
<p>With these in place, the rest of the CPU instructions can be simulated. Another few examples are shown below:</p>
<samp>
 <h3>Z80.js: Memory-handling instructions</h3>
 <pre>
    <s>// Push registers B and C to the stack (PUSH BC)</s>
    PUSHBC: <kbd>function</kbd>() {
        Z80._r.sp--;                               <s>// Drop through the stack</s>
	MMU.wb(Z80._r.sp, Z80._r.b);               <s>// Write B</s>
	Z80._r.sp--;                               <s>// Drop through the stack</s>
	MMU.wb(Z80._r.sp, Z80._r.c);               <s>// Write C</s>
	Z80._r.m = <var>3</var>; Z80._r.t = <var>12</var>;               <s>// 3 M-times taken</s>
    },

    <s>// Pop registers H and L off the stack (POP HL)</s>
    POPHL: <kbd>function</kbd>() {
        Z80._r.l = MMU.rb(Z80._r.sp);              <s>// Read L</s>
	Z80._r.sp++;                               <s>// Move back up the stack</s>
	Z80._r.h = MMU.rb(Z80._r.sp);              <s>// Read H</s>
	Z80._r.sp++;                               <s>// Move back up the stack</s>
	Z80._r.m = <var>3</var>; Z80._r.t = <var>12</var>;               <s>// 3 M-times taken</s>
    }

    <s>// Read a byte from absolute location into A (LD A, addr)</s>
    LDAmm: <kbd>function</kbd>() {
        <kbd>var</kbd> addr = MMU.rw(Z80._r.pc);              <s>// Get address from instr</s>
	Z80._r.pc += <var>2</var>;                            <s>// Advance PC</s>
	Z80._r.a = MMU.rb(addr);                   <s>// Read from address</s>
	Z80._r.m = <var>4</var>; Z80._r.t=<var>16</var>;                 <s>// 4 M-times taken</s>
    }</pre>
</samp>
<h2>Dispatch and reset</h2>
<p>With the instructions in place, the remaining pieces of the puzzle for the CPU are to reset the CPU when it starts up, and to feed instructions to the emulation routines. Having a reset routine allows for the CPU to be stopped and "rewound" to the start of execution; an example is shown below.</p>
<samp>
 <h3>Z80.js: Reset</h3>
 <pre>    reset: <kbd>function</kbd>() {
	Z80._r.a = <var>0</var>; Z80._r.b = <var>0</var>; Z80._r.c = <var>0</var>; Z80._r.d = <var>0</var>;
	Z80._r.e = <var>0</var>; Z80._r.h = <var>0</var>; Z80._r.l = <var>0</var>; Z80._r.f = <var>0</var>;
	Z80._r.sp = <var>0</var>;
	Z80._r.pc = <var>0</var>;      <s>// Start execution at 0</s>

	Z80._clock.m = <var>0</var>; Z80._clock.t = <var>0</var>;
    }</pre>
</samp>
<p>In order for the emulation to run, it has to emulate the fetch-decode-execute sequence detailed earlier. "Execute" is taken care of by the instruction emulation functions, but fetch and decode require a specialist piece of code, known as a "dispatch loop". This loop takes each instruction, decodes where it must be sent for execution, and dispatches it to the function in question.</p>
<samp>
 <h3>Z80.js: Dispatcher</h3>
 <pre><kbd>while</kbd>(<var>true</var>)
{
    <kbd>var</kbd> op = MMU.rb(Z80._r.pc++);              <s>// Fetch instruction</s>
    Z80._map[op]();                            <s>// Dispatch</s>
    Z80._r.pc &amp;= <var>65535</var>;                    <s>    // Mask PC to 16 bits</s>
    Z80._clock.m += Z80._r.m;                  <s>// Add time to CPU clock</s>
    Z80._clock.t += Z80._r.t;
}

Z80._map = [
    Z80._ops.NOP,
    Z80._ops.LDBCnn,
    Z80._ops.LDBCmA,
    Z80._ops.INCBC,
    Z80._ops.INCr_b,
    ...
];</pre>
</samp>
<h2>Usage in a system emulation</h2>
<p>Implementing a Z80 emulation core is useless without an emulator to run it. In the next part of this series, the work of emulating the Gameboy begins: I'll be looking at the Gameboy's memory map, and how a game image can be loaded into the emulator over the Web.</p>
<p>The complete Z80 core is available at: <a href="http://imrannazar.com/content/files/jsgb.z80.js">http://imrannazar.com/content/files/jsgb.z80.js</a>; please feel free to let me know if you encounter any bugs in the implementation.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jul 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Memory Usage of Constants in PHP</title>
 <link href="https://imrannazar.com/articles/php-const-memory-usage" rel="alternate" type="text/html" title="Memory Usage of Constants in PHP" />
 <id>https://imrannazar.com/articles/php-const-memory-usage</id>
 <summary>PHP provides two methods of defining constants: global-scope constants and class constants. A friend of mine, while discussing the issue with Derick Rethans, was informed that class constants are more memory efficient; this article documents my investigation into the reasons behind that assertion.</summary>
 <category term="Articles" />
 <published>Thu, 24 Jun 2010 21:11:30 +0000</published>
 <content type="text/html"><![CDATA[
   <p>A common requirement in the development of web applications is that the interface is portable between languages: any phrases which appear within the interface must be in the viewer's preferred language. The consequence of this is that, instead of the phrases themselves, definitions which refer to the phrases must be used throughout the website.</p>
<p>In PHP, one of the more common ways to implement this is to generate multiple "phrase files", each of which contains all the phrases required for a given language. Each phrase is defined as a constant; an example of such a phrase file could run as follows.</p>
<samp>
 <h3>phrases.tr.php: Turkish phrase file</h3>
 <pre><kbd>define</kbd>(<var>'_WELCOME'</var>,       <var>'Ho&#x015f;geldiniz!'</var>);
<kbd>define</kbd>(<var>'_FREE_DELIVERY'</var>, <var>'&Uuml;cretsiz da&#x011f;&#x0131;tma'</var>);
<kbd>define</kbd>(<var>'_BRANDS'</var>,        <var>'Markalar'</var>);
<kbd>define</kbd>(<var>'_COMPUTERS'</var>,     <var>'Bilgisayarlar'</var>);</pre>
</samp>
<p>The object-oriented approach yields another method of holding these translation phrases, as class constants within a phrases class. This alternative approach would be performed as below.</p>
<samp>
 <h3>phrases.tr.php: Turkish phrase file</h3>
 <pre><kbd>class</kbd> Phrases
{
    <kbd>const</kbd> WELCOME       = <var>'Ho&#x015f;geldiniz!'</var>;
    <kbd>const</kbd> FREE_DELIVERY = <var>'&Uuml;cretsiz da&#x011f;&#x0131;tma'</var>;
    <kbd>const</kbd> BRANDS        = <var>'Markalar'</var>;
    <kbd>const</kbd> COMPUTERS     = <var>'Bilgisayarlar'</var>;
}</pre>
</samp>
<p>Since there are probably a large number of these phrases, it makes sense to seek the most memory-efficient of these two constructs: in other words, the one which takes the least amount of memory to be held. It might be expected that both methods of defining the phrase file would cause the same amount of memory to be taken up; this is not the case.</p>
<p>(A note: the analysis presented below is based on the definitions held in PHP 5.2.10; the values produced may differ in future versions.)</p>
<h2>Storage of a global constant</h2>
<p>The first of the two methods above defines a series of constants in the global scope; internally to PHP, these were initially stored as an array of <code>struct zend_constant</code>. The layout of this data structure, and the memory used, are derived from the basic <code>zval</code> structure used by PHP to hold values.</p>
<figure class="invertable">
 <img src="/content/img/php-const-global-php3.png" alt="Original scheme for global constants">
 <figcaption>Figure 1: Original storage scheme for global constants</figcaption>
</figure>
<p>This data structure is memory-efficient, being able to store the name and value of the constant, as well as the other data required by PHP for a value, such as the reference count. The problem with defining <code>zend_constants</code> as an array is that the time taken to find a particular constant grows linearly with the number of constants that are defined; since the PHP interpreter itself sets constants such as <code>PHP_VERSION</code>, there will always be a disadvantage for user code in terms of speed.</p>
<p>To resolve this, a <code>HashTable</code> data structure was introduced with PHP 3, to allow for logarithmic-time searching of the constants. The <code>HashTable</code> uses <code>Bucket</code>s to store its data entries, each of which has a name attached.</p>
<figure class="invertable">
 <img src="/content/img/php-const-global-hash.png" alt="Hashtable scheme for global constants">
 <figcaption>Figure 1a: Hashtable storage scheme for global constants</figcaption>
</figure>
<p>The trade-off in using a hash structure like this, is that more memory is taken for storage of the hashes and key lengths. In total, storage of a global constant takes 42 bytes before the strings for name and value are counted.</p>
<h2>Storage of a class constant</h2>
<p>With the introduction of objects in PHP 4, a new line of thinking was employed for class-level constants: if a <code>HashTable</code> is used, and a hash of the constant name is stored, the name itself doesn't need to be stored alongside it. This allows a good chunk of space to be saved, and the structure of the storage to be simplified somewhat.</p>
<figure class="invertable">
 <img src="/content/img/php-const-class.png" alt="Scheme for class constants">
 <figcaption>Figure 2: Storage scheme for class constants</figcaption>
</figure>
<p>As can be seen here, the name of the constant isn't stored at all once its hash has been calculated. This means that the <code>zend_constant</code> structure can be eliminated, leaving only the <code>zval</code>. As a result, a class constant needs 26 bytes to be stored, before the value is counted.</p>
<h2>Conclusions</h2>
<p>Two conclusions can be drawn from this analysis:</p>
<ul>
 <li>If you're putting together a script that demands a long series of constants, such as a translation table, it may be advisable to use a class to hold the constants instead of defining them in the global scope;</li>
 <li>If Derick Rethans informs you that class constants take up less memory than global ones, you can take him at his word.</li>
</ul>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, June 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Venn Diagrams in PHP with imagick</title>
 <link href="https://imrannazar.com/articles/php-venn-diagrams" rel="alternate" type="text/html" title="Venn Diagrams in PHP with imagick" />
 <id>https://imrannazar.com/articles/php-venn-diagrams</id>
 <summary>Visualising the overlap between two sets of data is often achieved through Venn diagrams, but such diagrams can be difficult to render in a web development environment. This article covers the mathematics and geometry behind the Venn diagram, and a simple implementation of the algorithms involved in calculating the appropriate dimensions.</summary>
 <category term="Articles" />
 <published>Thu, 20 May 2010 08:26:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One common problem in data visualisation is the representation of two sets of data, which have a common subset of elements: a percentage of their contents which are present in both. The obvious solution to this issue is to draw a Venn diagram: two overlapping circles, where the overlap represents the percentage of common elements.</p>
<figure>
 <img src="/content/img/venn.png" alt="Venn diagram">
 <figcaption>Figure 1: A sample Venn diagram, with data sets of green and blue, and common elements in cyan</figcaption>
</figure>
<p>The main issue in drawing a Venn diagram is, given the percentage of overlap, determining the placement of the circles such that it visually matches the stated overlap. Once the circle dimensions and placements have been worked out, the image manipulation is relatively straightforward.</p>
<p>In this article, I'll be using PHP to demonstrate the implementation, and the <code>imagick</code> interface to ImageMagick in order to draw and output the image.</p>
<h2>Geometry: Overlapping circles</h2>
<p>Mathematically, two overlapping circles will cross each other at two points: a line between these two points is a <em>chord</em> of the circles, and the area contained within each chord segment by this line is 50% of the total overlap.</p>
<figure class="invertable">
 <img src="/content/img/venn-dimensions.png" alt="Venn diagram dimensions">
 <figcaption>Figure 2: Circle segment dimensions</figcaption>
</figure>
<p>In order to correctly place the circles, it's important to find out what <em>x</em> and <em>h</em> are in the above diagram; knowing these values will allow for easy calculation of the horizontal positions. By using the <a href="http://en.wikipedia.org/wiki/Circle_segment#Formula">standard formulae</a> for area and angle of a circle segment, the following equation can be obtained.</p>
<figure class="invertable">
 <img src="/content/img/venn-formula.png" alt="Formula for sagitta length">
 <figcaption>Formula 1: Length of the sagitta</figcaption>
</figure>
<p>By solving this equation, we can get the length of the sagitta, <em>x</em>. The problem presented by this equation, however, is that it cannot be solved analytically by working with the equation terms. A numerical approach will need to be used, to find a solution.</p>
<h2>The Newton-Raphson iterative method</h2>
<p>One of the most common numerical algorithms for solving an equation is the Newton-Raphson method, also known as Newton's method. It uses the gradient of the function at a particular point, to guess the next point. By picking a good starting point, it's possible to quickly narrow down a solution to the function (the point at which it crosses the x-axis).</p>
<figure class="invertable">
 <img src="/content/img/venn-nr.png" alt="Newton-Raphson method">
 <figcaption>Figure 3: An example of the Newton-Raphson method</figcaption>
</figure>
<p>As can be seen in the above figure, the algorithm follows the gradient line down to the x-axis, and uses the crossing point there as its next guess for the solution. Taking another gradient from the function at that point, the algorithm homes in on the solution within (in the above case) 4 or 5 iterations. When used on a formula, the gradient is represented by the differential of the formula in question; for the sagitta length formula, the differential is:</p>
<figure class="invertable">
 <img src="/content/img/venn-diff-formula.png" alt="Differential of sagitta length">
 <figcaption>Formula 2: Differential of the sagitta length</figcaption>
</figure>
<p>With both formulae to hand (the function itself and the differential), the iteration process is a simple calculation:</p>
<figure class="invertable">
 <img src="/content/img/venn-nr-formula.png" alt="Newton-Raphson formula">
 <figcaption>Formula 3: The Newton-Raphson algorithm</figcaption>
</figure>
<p>This calculation can be repeated until the answer is close to the expected solution: in other words, when successive iterations don't result in a significant change to the answer. The definition of "significant change" depends on the problem: in this case, I'll be using "the same to four decimal places".</p>
<p>As an example, suppose that the Venn diagram in Figure 1 is being generated: a diagram showing 20% overlap, where each circle has a radius of 150 pixels. Plugging these values into the Newton-Raphson solver shows the following values for each iteration.</p>
<samp>
 <h3>Iteration results for an example diagram</h3>
 <pre>0.0000
94.2478
102.7742
103.0570
<strong>103.0573
103.0573</strong></pre>
</samp>
<p>As can be seen, the solver quickly converges on the answer for the length <em>x</em>. From here, <em>h</em> can be calculated as the difference between <em>x</em> and the radius, and the angle <em>&theta;</em> as:</p>
<figure class="invertable">
 <img src="/content/img/venn-angle-formula.png" alt="Circle segment angle formula">
 <figcaption>Formula 4: Angle for circle segment</figcaption>
</figure>
<h2>Implementing the solver</h2>
<p>In PHP, the solver can be implemented by defining the sagitta formula and its differential as two functions, and using a recursive function to run through their values. The following implementation contains a "safety valve" for the solver, for the general case where the equations may cause a divergence if the solver starts at <em>x</em>=0. In the case of this equation, the safety valve is unnecessary, since the algorithm will always converge if it starts at 0; it is included below for completeness.</p>
<samp>
 <h3>Iterative solver implementation</h3>
 <pre><kbd>class</kbd> Sagitta
{
	<s>// The sagitta length formula</s>
	<kbd>static function</kbd> f($x, $r, $P)
	{
		<kbd>return acos</kbd>($x/$r)-(<var>M_PI</var>*$P)-(($x/($r*$r))*<kbd>sqrt</kbd>(($r+$x)*($r-$x)));
	}

	<s>// Differential of the length</s>
	<kbd>static function</kbd> fp($x, $r, $P)
	{
		$s = <kbd>sqrt</kbd>(1-(($x*$x)/($r*$r)));
		<kbd>return</kbd> (((($x*$x)/($r*$r*$r)) - (<var>1</var>/$r)) / $s) - ($s/$r);
	}

	<s>// Recursive solver
	// Built-in safety valve at 10 levels down</s>
	<kbd>static function</kbd> solve($x, $r, $P, $level=<var>10</var>, $precision=<var>0.0001</var>)
	{
		$xn = $x - (<kbd>self</kbd>::f($x,$r,$P) / <kbd>self</kbd>::fp($x,$r,$P));
		<kbd>if</kbd>($level &amp;&amp; (<kbd>abs</kbd>($xn - $xn) &gt; $precision))
			<kbd>return self</kbd>::solve($xn, $r, $P, $level-<var>1</var>);
		<kbd>else
			return</kbd> $xn;
	}
}

$radius = <var>150</var>;
$overlap = <var>0.2</var>;

<s>// Each circle contains half of the overlap; use this to calculate x</s>
$x0 = <var>0</var>;
$x = Sagitta::solve($x0, $radius, $overlap/<var>2</var>);</pre>
</samp>
<h2>Drawing the Venn diagram</h2>
<p>Using PHP and <code>imagick</code>, the Venn diagram can be drawn quickly and efficiently based on the value for <em>x</em> obtained above. There are, however, a few issues that must be resolved:</p>
<ul>
 <li><strong>Circle placement</strong>: In order to plot a circle in <code>imagick</code>, its centre coordinate must be given, and this must be calculated horizontally for both circles. For the left-hand circle, this is simply one radius in from the left of the image. The right-hand circle would be three radii from the left edge, if there were no overlap; from Figure 2, it can be seen that there is 2<em>h</em> of overlap, so this must be subtracted from the horizontal coordinate of the right-hand circle.</li>
 <li><strong>Intersection</strong>: The two circles can be drawn easily, but the circle segments representing the intersection could cause difficulty. Fortunately, <code>imagick</code> provides a construct for drawing an ellipse segment: given two angles, it will plot the arc and chord between them, and fill the space in the "fill colour" defined beforehand.</li>
 <li><strong>Image size</strong>: As with the circle placement, the horizontal dimension of the image is lower than may be expected. Without overlap, the image would be as wide as both circle diameters put together; the overlap of 2<em>h</em> must again be subtracted from this if the image is not to be too wide.</li>
</ul>
<p>Having taken these issues into account, the following code will generate the Venn diagram given <em>x</em>.</p>
<samp>
 <h3>Image rendering implementation</h3>
 <pre>$h = $radius - $x;
$theta = <kbd>acos</kbd>($x/$r) * (<var>180</var> / <var>M_PI</var>);

<s>// 5 pixels of padding around the Venn</s>
$padding = <var>5</var>;
$overlap_width = <var>2</var>*$h;

$im = <kbd>new</kbd> Imagick();
$im-&gt;newImage($r*<var>4</var> - $overlap_width + ($padding*<var>2</var>),
              $r*<var>2</var> + ($padding*<var>2</var>),
	      <kbd>new</kbd> ImagickPixel(<var>'white'</var>));

$draw = <kbd>new</kbd> ImagickDraw();

<s>// Left-hand circle, in green</s>
$draw-&gt;setFillColor(<kbd>new</kbd> ImagickPixel(<var>'#88ff88'</var>));
$draw-&gt;ellipse($r + $padding, $r + $padding,
               $r, $r,
	       <var>0</var>, <var>360</var>);

<s>// Right-hand circle, in blue</s>
$draw-&gt;setFillColor(<kbd>new</kbd> ImagickPixel(<var>'#8888ff'</var>));
$draw-&gt;ellipse($r*<var>3</var> - $overlap_width + $padding, $r + $padding,
               $r, $r,
	       <var>0</var>, <var>360</var>);

<s>// Intersection, in cyan
// Angles are specified in degrees, from the rightmost point of the circle</s>
$draw-&gt;setFillColor(<kbd>new</kbd> ImagickPixel(<var>'#88ffff'</var>));

<s>// Left-hand segment (right half of intersection)
// -theta is in the top right, +theta in the bottom right</s>
$draw-&gt;ellipse($r + $padding, $r + $padding,
               $r, $r,
	       -$theta, $theta);

<s>// Right-hand segment (left half of intersection)
// 180-theta is in the bottom left, 180+theta in the top left</s>
$draw-&gt;ellipse($r*<var>3</var> - $overlap_width + $padding, $r + $padding,
               $r, $r,
	       <var>180</var>-$theta, <var>180</var>+$theta);

<s>// Image bounding rectangle</s>
$draw-&gt;setStrokeColor(<kbd>new</kbd> ImagickPixel(<var>'black'</var>));
$draw-&gt;setStrokeWidth(<var>1</var>);
$draw-&gt;setFillOpacity(<var>0</var>);
$draw-&gt;rectangle(0, 0,
                 $r*<var>4</var> - $overlap_width + ($padding*<var>2</var>) - <var>1</var>,
		 $r*<var>2</var> + $padding - <var>1</var>);

<s>// Output image</s>
$im-&gt;drawImage($draw);
$im-&gt;setImageFormat(<var>'png'</var>);
<kbd>header</kbd>(<var>'Content-type: image/png'</var>);
<kbd>echo</kbd> $im;</pre>
</samp>
<p>The above code results in Figure 1.</p>
<h2>Issues and enhancements</h2>
<p>One problem that remains with this implementation is the range of overlap percentages. If an overlap of less than 0% is given (if, in other words, the sets don't overlap), the equations above result in complex roots and PHP crashes while attempting to calculate them. Similarly, if the overlap is specified as more than 100%, this should reverse the positions of the sets in the Venn diagram; instead, the equations will produce a small section of one circle which is rendered as all intersection. A simple range check on the overlap percentage can alleviate these issues, and prevent them from being passed through to the script.</p>
<p>Another limitation is the inherent tie of two sets that is implied by this script; it is not possible to specify an overlap between three sets using this model. The geometry to allow for three intersecting circles to be specified is left as an exercise for the reader.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, May 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Light</title>
 <link href="https://imrannazar.com/scifi/light" rel="alternate" type="text/html" title="Sci-fi Shorts: Light" />
 <id>https://imrannazar.com/scifi/light</id>
 <summary>A curious trespasser investigates the nuclear fallout zone around Cheyenne Mountain. First published in the &lt;a href=&quot;http://www.lulu.com/product/p/r/14247979&quot;&gt;My Writers Circle &quot;Rascals&quot; anthology&lt;/a&gt;; flash fiction.</summary>
 <category term="Original Writings" />
 <published>Sun, 02 May 2010 17:39:32 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Out here, you can draw a square a hundred miles on a side, and find no-one
living inside. The whole area had been evacuated when the nuclear pile under
Cheyenne Mountain had grown to a critical size, and the meltdown irradiated
the whole county. All the towns stood empty, cars had been left abandoned:
nothing moved.
</p><p>
Apart from a motorcycle on I-70. The road is rutted, but she makes her way
around the holes, weaving across the lanes towards Denver. She'd found out
about Cheyenne, and had cut across fields to avoid the cordon; there was
something under the mountain, and she was here to find out what.
</p><p>
She rolls up to the tunnel through the mountain, filled in by the collapse
after the meltdown. The infill has been smoothed over, and a porthole window
fitted at around waist height. She peers in, expecting to see only rock and
stone, and sees &mdash;
</p><p>
Light. Spirals of light against a perfectly dark background, as if there were
galaxies of stars through that porthole. A whole universe, underneath the
mountain.
</p><p>
They say the universes in this ring start in the same place, and grow outward.
They don't say where that place is.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: New Science</title>
 <link href="https://imrannazar.com/scifi/new-science" rel="alternate" type="text/html" title="Sci-fi Shorts: New Science" />
 <id>https://imrannazar.com/scifi/new-science</id>
 <summary>Winning entry for a writing contest, with the length stipulation of exactly 100 words. First published by &lt;a href=&#039;http://www.mywriterscircle.com/&#039;&gt;My Writers Circle&lt;/a&gt;; flash fiction.</summary>
 <category term="Original Writings" />
 <published>Mon, 15 Mar 2010 16:28:20 +0000</published>
 <content type="text/html"><![CDATA[
   <p>When approbation was finally given for the project, Ryan was immediately ready to put together the prototype. Just two weeks later, the team met in the portico of University College, to witness the results.</p>
<p>Ryan explained that, for testing purposes, the subject would be a starfish from the Bond Street aquarium. He wheeled the laser in, and fired; the starfish promptly vanished.</p>
<p>"I thought you were demonstrating levitation to six feet, Dr Ryan," said one of his assistants, as they gathered over a star-shaped hole in the pavement.</p>
<p>"The laser must be upside down; give me a minute," Ryan answered.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Discordian Dates in Java</title>
 <link href="https://imrannazar.com/articles/java-discordian-dates" rel="alternate" type="text/html" title="Discordian Dates in Java" />
 <id>https://imrannazar.com/articles/java-discordian-dates</id>
 <summary>Date handling, and especially conversion between different calendars, can be a complex issue to deal with. This article introduces the concept of calendar conversion in Java, and the issues that need to be dealt with when performing such conversions, by building a handler for the Discordian calendar and investigating the mappings between months in the Gregorian calendar and the Discordian seasons.</summary>
 <category term="Articles" />
 <published>Mon, 08 Mar 2010 18:03:28 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The representation of dates is something that goes back many thousands of years: each tradition and religion has its own way of representing and calculating the calendar, and there is seldom an easy way to move between the calendars. Calculating a date in one calendar, given the same date in another calendar, can involve a laborious set of operations based on the phase of the moon, the orbital inclination and other such things.</p>
<h2>The Discordian calendar</h2>
<p>Discordianism uses a calendar inspired by the well-established Gregorian calendar, with prominence given to the number five. As opposed to twelve months, there are five seasons with a regular number of days in each season:</p>
<figure>
 <table>
  <thead><tr><th>Season</th><th>Days</th></tr></thead>
  <tbody>
   <tr><td>Chaos</td><td>73</td></tr>
   <tr><td>Discord</td><td>73</td></tr>
   <tr><td>Confusion</td><td>73</td></tr>
   <tr><td>Bureaucracy</td><td>73</td></tr>
   <tr><td>The Aftermath</td><td>73</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Seasons of the Discordian calendar</figcaption>
</figure>
<p>This results in a year of 365 days, in alignment with the Gregorian calendar; as a result, a given day in the Discordian calendar always corresponds to the same day in Gregorian.</p>
<p>In addition to there being five seasons, each week consists of five days: Sweetmorn, Boomtime, Pungenday, Prickle-Prickle and Setting Orange. Because the calendar is aligned to Gregorian, each Discordian year consists of 73 weeks of 5 days; because of this, each day in the calendar always has both the same day name and the same date.</p>
<p>In the Gregorian calendar, leap days are added in 97 out of 400 years, on a 4-yearly cycle. The same process applies in Discordianism, with St. Tib's day inserted between Chaos the 59th and 60th (February 28th and March 1st).</p>
<p>A final detail is that the Discordian calendar begins in 1166 BCE; years are counted in step with Gregorian since that time, and marked <em>anno discordia</em>, or "Years of Our Lady of Discord". A few examples of dates in both calendars follow.</p>
<samp>
 <h3>Example dates in Discordian and Gregorian</h3>
 <pre>Chaos 1st, 3000             = January 1st, 1834
Bureaucracy 70th, 3155      = October 16th, 1989
St. Tib's Day, 3178         = February 29th, 2012</pre>
</samp>
<h2>Converting between the calendars</h2>
<p>Because the Discordian calendar is very regular, conversion between Discordian and Gregorian dates is relatively simple. All that is required is to calculate the offsets for year, day and month.</p>
<samp>
 <h3>Discordian date calculation, given year and day of year</h3>
 <pre>DYear = Year + <var>1166</var>

<s>; Handle leap years</s>
IF Year is-a-leap-year THEN
    IF Day = <var>59</var> THEN
        DSeasonday = <var>"St. Tib's Day"</var>
    ELSE IF Day &gt; <var>59</var>
<s>        ; Days after Feb 29th need to be shifted up to make this
	; year into a regular 365-day year, for calculation purposes</s>
	Day = Day - <var>1</var>
    END IF
END IF

SeasonNames = [<var>"Chaos"</var>, <var>"Discord"</var>, <var>"Confusion"</var>, <var>"Bureaucracy"</var>, <var>"The Aftermath"</var>]
DayNames = [<var>"Sweetmorn"</var>, <var>"Boomtime"</var>, <var>"Pungenday"</var>, <var>"Prickle-Prickle"</var>, <var>"Setting Orange"</var>]

IF DSeasonday is-not-already-set THEN
    DSeason = SeasonNames[Day / <var>73</var>]
    DWeekday = DayNames[Day MOD <var>5</var>]
    DSeasonday = Day MOD <var>73</var>
END IF</pre>
</samp>
<p>The above is a pseudocode sample for converting a date into Discordian, and takes account of the special case for leap years. Converting from Discordian back into Gregorian dates is similarly simple. The only complication involved is the leap-year case, where the date as reported by the Discordian calendar is one day ahead of where it would be in other years.</p>
<samp>
 <h3>Gregorian day/year calculation from Discordian</h3>
 <pre>Year = DYear - 1166
Day = (DSeasonNum - 1) * 73 + DSeasondayNum

IF Year is-a-leap-year THEN
    IF DSeasonday = "St. Tib's Day" THEN
        Day = 60
    ELSE IF Day &gt;= 60
        Day = Day + 1
    END IF
END IF</pre>
</samp>
<h2>Java implementation</h2>
<p>Writing the above algorithms in Java is made very simple by the existence of <code>java.util.Calendar</code>, the date/calendar calculation class; in particular, the <code>GregorianCalendar</code> subclass allows for calculation of leap years in a quick and efficient manner. The following code implements conversions from one calendar to the other, providing a readable representation of the date in either case.</p>
<samp>
 <h3>ddate.java: Discordian/Gregorian date conversion</h3>
 <pre><kbd>import</kbd> java.util.Date;
<kbd>import</kbd> java.util.Calendar;
<kbd>import</kbd> java.util.GregorianCalendar;

<kbd>public class</kbd> ddate
{
    <kbd>private int</kbd> _year, _season, _yearDay, _seasonDay, _weekDay;
    <kbd>private boolean</kbd> _isLeap;

    <kbd>private</kbd> String[] _seasonNames = {<var>"Chaos"</var>,<var>"Discord"</var>,<var>"Confusion"</var>,<var>"Bureaucracy"</var>,<var>"The Aftermath"</var>};
    <kbd>private</kbd> String[] _dayNames = {<var>"Sweetmorn"</var>,<var>"Boomtime"</var>,<var>"Pungenday"</var>,<var>"Prickle-Prickle"</var>,<var>"Setting Orange"</var>};

    <kbd>public</kbd> ddate(Date d)
    {
        GregorianCalendar gc = <kbd>new</kbd> GregorianCalendar();
	gc.setTime(d);

	_year = gc.get(Calendar.YEAR) + <var>1166</var>;
	_yearDay = gc.get(Calendar.DAY_OF_YEAR);
	_isLeap = gc.isLeapYear(gc.get(Calendar.YEAR));

	int yd = _yearDay - <var>1</var>;

	<kbd>if</kbd>(_isLeap &amp;&amp; yd &gt; <var>59</var>)
	    yd--;

	_season = (yd / <var>73</var>) + <var>1</var>;
	_weekDay = (yd % <var>5</var>) + <var>1</var>;
	_seasonDay = (yd % <var>73</var>) + <var>1</var>;
    }

    <kbd>public int</kbd> getYear()          { <kbd>return</kbd> _year; }
    <kbd>public int</kbd> getSeason()        { <kbd>return</kbd> _season; }
    <kbd>public int</kbd> getYearDay()       { <kbd>return</kbd> _yearDay; }
    <kbd>public int</kbd> getSeasonDay()     { <kbd>return</kbd> _seasonDay; }
    <kbd>public</kbd> String getSeasonName() { <kbd>return</kbd> _seasonNames[_season-<var>1</var>]; }
    <kbd>public</kbd> String getDayName()    { <kbd>return</kbd> _dayNames[_yearDay-<var>1</var>]; }

    <kbd>public</kbd> String toString()
    {
        <kbd>if</kbd>(_isLeap &amp;&amp; _yearDay == <var>59</var>)
	{
	    <kbd>return</kbd> <var>"St. Tib's Day, "</var> + Integer.toString(_year);
	}
	<kbd>else</kbd>
	{
            <kbd>return</kbd> _dayNames[_weekDay-<var>1</var>] + <var>", " </var>+
	           _seasonNames[_season-<var>1</var>] + <var>" "</var> +
	           Integer.toString(_seasonDay) + <var>", "</var> +
	           Integer.toString(_year);
	}
    }

    <kbd>public</kbd> Date getTime()
    {
        GregorianCalendar gc = <kbd>new</kbd> GregorianCalendar();
	gc.set(Calendar.YEAR, _year - <var>1166</var>);
	gc.set(Calendar.DAY_OF_YEAR, _yearDay);
	
	<kbd>return</kbd> gc.getTime();
    }
}</pre>
</samp>
<samp>
 <h3>Sample usage of ddate.java</h3>
 <pre>Calendar foo = <kbd>new</kbd> Calendar();
foo.setTime(<kbd>new</kbd> Date());
foo.add(Calendar.DAY, <var>-1</var>);

ddate bar = <kbd>new</kbd> ddate(foo.getTime());
System.out.println(<var>"Yesterday was "</var> + bar.toString());</pre>
</samp>
<h2>Extending the conversion</h2>
<p>The conversion process detailed above doesn't include the ten Holy Days of the Discordian calendar: a Holy Day falls on the 5th and 50th of each season. Since these Days occur with such regularity, it poses no extra difficulty to provide an interface for this, and such an interface has been left out of the above code in the interest of brevity.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Mar 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">linecolor.pl: Rule-based Line Colours in irssi</title>
 <link href="https://imrannazar.com/hacks/irssi-linecolor" rel="alternate" type="text/html" title="linecolor.pl: Rule-based Line Colours in irssi" />
 <id>https://imrannazar.com/hacks/irssi-linecolor</id>
 <summary>The irssi IRC client has a built-in capability for rule-based highlighting of nicknames, but does not allow for the full line to be highlighted; nor does irssi allow arbitrary colours to be set against different rules. linecolor is an extension script for irssi that allows for this functionality to be added, in an intuitive fashion.</summary>
 <category term="Quick Hacks" />
 <published>Mon, 01 Feb 2010 14:27:30 +0000</published>
 <content type="text/html"><![CDATA[
   <p>As any user of IRC will tell you, the <code>ignore</code> command is a gift from the Gods: it allows you to ignore any output being generated by a particular person or nickname, whether it's plain noise or something downright malicious. In the <code>irssi</code> client, you can go one further and specify ignore for any messages which match a given regular expression, from whichever nick they originate.</p>
<p>In some cases, you may not wish to ignore a person entirely; they may have the occasional insight into a topic, but simply act foolishly for most of the day. Alternatively, a particularly chatty bot may have some useful features, but will simply get in the way of channel discussion most of the time. In these situations, a halfway house between full participation and total ignorance is required.</p>
<h2>Line coloring</h2>
<p>If the channel window of a given IRC client has a standard high-contrast colour scheme (either white text on a black background, or vice versa), it's trivial to define a halfway point between text being fully visible and text being altogether hidden from view: grey text. Similarly, any lines of text that need particular attention paid to them can be highlighted in red, as an example. What is required is a way to denote lines worthy of attention, and lines eligible for half-ignore.</p>
<p>For the <code>irssi</code> client, the <code>nickcolor</code> extension comes close: it is able to assign a specific colour to a given nick, and highlight the rest in random colours. Unfortunately, there are a few drawbacks with <code>nickcolor</code> as it stands:</p>
<ul>
 <li>Only the nick is coloured, leaving the line in its normal colour; this is insufficient for our purposes.
 <li>Other nicks get coloured in, aside from the ones required; ideally, these should be left at their normal state.</li>
 <li>As the name implies, <code>nickcolor</code> only works by nickname; it cannot apply regex matching on messages for the purpose of highlighting.</li>
</ul>
<p>To address these issues, an adapted version of the <code>nickcolor</code> script is put forward in this article, which I've renamed as <code>linecolor</code>. An example of its usage would be as follows.</p>
<samp>
 <h3><code>linecolor</code>: Sample usage</h3>
 <pre>/color set Bucket 14
/color rset ^Bucket 14</pre>
</samp>
<p>The above rules specify that any output from "Bucket" is to be marked as colour #14 (grey), and any output from any nick starting with the word "Bucket" is also to be marked grey. The resulting output is shown below.</p>
<figure>
 <img src="/content/img/irssi-linecolor-output.png" alt="Example of line colouring">
 <figcaption>Figure 1: Colouring IRC lines for half-ignore</figcaption>
</figure>
<p>The code is shown below, and is also available from <a href="/content/img/linecolor.txt">http://imrannazar.com/content/img/linecolor.txt</a>.</p>
<samp>
 <h3><code>linecolor</code>: An irssi script for rule-based line colouring</h3>
 <pre><s># Line Color - Assign colours to lines from specific nicks, or matching patterns
# Adapted from "Nick Color" by Timo Sirainen, as modified by Ian Petersi</s>

<kbd>use</kbd> strict;
<kbd>use</kbd> Irssi <var>20020101.0250</var> ();
<kbd>use vars</kbd> qw($VERSION %IRSSI); 
$VERSION = <var>"1.2"</var>;
%IRSSI = (
    authors     =&gt; <var>"Timo Sirainen, Ian Petersi, Imran Nazar"</var>,
    contact	=&gt; <var>"tss\@iki.fi"</var>, 
    name        =&gt; <var>"Line Color"</var>,
    description =&gt; <var>"assign colours to lines through nick/regex rules"</var>,
    license	=&gt; <var>"Public Domain"</var>,
    url		=&gt; <var>"http://irssi.org/"</var>,
    changed	=&gt; <var>"2010-01-28T18:30+0000"</var>
);

<s># hm.. i should make it possible to use the existing one..</s>
Irssi::theme_register([
  <var>'pubmsg_hilight'</var>, <var>'{pubmsghinick $0 $3 $1}$2'</var>
]);

<kbd>my</kbd> %saved_colors;
<kbd>my</kbd> %saved_regex_colors;
<kbd>my</kbd> %session_colors = {};
<kbd>my</kbd> @colors = qw/<var>2 3 4 5 6 7 9 10 11 12 13</var>/;

<kbd>sub</kbd> load_colors {
  <kbd>open</kbd> COLORS, <var>"$ENV{HOME}/.irssi/saved_colors"</var>;

  <kbd>while</kbd> (&lt;COLORS&gt;) {
    <s># I don't know why this is necessary only inside of irssi</s>
    <kbd>my</kbd> @lines = <kbd>split</kbd> <var>"\n"</var>;
    <kbd>foreach my</kbd> $line (@lines) {
      <kbd>my</kbd>($type, $nick, $color) = <kbd>split</kbd> <var>":"</var>, $line;
      <kbd>if</kbd> ($type <kbd>eq</kbd> <var>"NICK"</var>) {
        $saved_colors{$nick} = $color;
      } <kbd>elsif</kbd> ($type <kbd>eq</kbd> <var>"REGEX"</var>) {
        $saved_regex_colors{$nick} = $color;
      }
    }
  }

  <kbd>close</kbd> COLORS;
}

<kbd>sub</kbd> save_colors {
  <kbd>open</kbd> COLORS, <var>"&gt;$ENV{HOME}/.irssi/saved_colors"</var>;

  <kbd>foreach my</kbd> $nick (<kbd>keys</kbd> %saved_colors) {
    <kbd>print</kbd> COLORS <var>"NICK:$nick:$saved_colors{$nick}\n"</var>;
  }
  <kbd>foreach my</kbd> $regex (<kbd>keys</kbd> %saved_regex_colors) {
    <kbd>print</kbd> COLORS <var>"REGEX:$regex:$saved_regex_colors{$regex}\n"</var>;
  }
  Irssi::print(<var>"Saved colors to $ENV{HOME}/.irssi/saved_colors"</var>);

  <kbd>close</kbd> COLORS;
}

<s># If someone we've colored (either through the saved colors, or the hash
# function) changes their nick, we'd like to keep the same color associated
# with them (but only in the session_colors, ie a temporary mapping).</s>

<kbd>sub</kbd> sig_nick {
  <kbd>my</kbd> ($server, $newnick, $nick, $address) = @_;
  <kbd>my</kbd> $color;

  $newnick = <kbd>substr</kbd> ($newnick, <var>1</var>) <kbd>if</kbd> ($newnick =~ <var>/^:/</var>);

  <kbd>if</kbd> ($color = $saved_colors{$nick}) {
    $session_colors{$newnick} = $color;
  } <kbd>elsif</kbd> ($color = $session_colors{$nick}) {
    $session_colors{$newnick} = $color;
  }
}

<kbd>sub</kbd> find_color {
  <kbd>my</kbd> ($server, $msg, $nick, $address, $target) = @_;
  <kbd>my</kbd> $chanrec = $server-&gt;channel_find($target);
  <kbd>return if not</kbd> $chanrec;
  <kbd>my</kbd> $nickrec = $chanrec-&gt;nick_find($nick);
  <kbd>return if not</kbd> $nickrec;
  <kbd>my</kbd> $nickmode = $nickrec-&gt;{op} ? <var>"@"</var> : $nickrec-&gt;{voice} ? <var>"+"</var> : <var>""</var>;

  <s># Has the user assigned this nick a color?</s>
  <kbd>my</kbd> $color = $saved_colors{$nick};

  <s># Have -we- already assigned this nick a color?</s>
  <kbd>if</kbd> (!$color) {
    $color = $session_colors{$nick};
  }

  <s># Does the message match any color regexen?</s>
  <kbd>if</kbd> (!$color) {
    <kbd>foreach my</kbd> $r (<kbd>keys</kbd> %saved_regex_colors) {
      <kbd>if</kbd> ($msg =~ m<var>/($r)/</var>i) {
        $color = $saved_regex_colors{$r};
	<kbd>last</kbd>;
      }
    }
  }

  <kbd>if</kbd> (!$color) {
    $color = <var>0</var>;
  }

  <kbd>return</kbd> $color;
}

<s># FIXME: breaks /HILIGHT etc.</s>
<kbd>sub</kbd> sig_public {
  <kbd>my</kbd> ($server, $msg, $nick, $address, $target) = @_;
  <kbd>my</kbd> $color = find_color(@_);

  <kbd>if</kbd> ($color) {
    $color = <var>"0"</var>.$color <kbd>if</kbd> ($color &lt; <var>10</var>);
    $server-&gt;command(<var>'/^format pubmsg {pubmsgnick $2 {pubnick '</var>.
    	<kbd>chr</kbd>(<var>3</var>).$color.<var>'$0'</var>.
	<kbd>chr</kbd>(<var>3</var>).<var>'15}}'</var>.<kbd>chr</kbd>(<var>3</var>).$color.<var>'$1'</var>);
  } <kbd>else</kbd> {
    $server-&gt;command(<var>'/^format pubmsg {pubmsgnick $2 {pubnick $0}}$1'</var>);
  }
}

<kbd>sub</kbd> sig_action {
  <kbd>my</kbd> ($server, $msg, $nick, $address, $target) = @_;
  <kbd>my</kbd> $color = find_color(@_);

  <kbd>if</kbd>($color) {
    $server-&gt;command(<var>'/^format action_public {pubaction '</var>.
    	<kbd>chr</kbd>(<var>3</var>).$color.<var>'$0'</var>.
	<kbd>chr</kbd>(<var>3</var>).<var>'15}'</var>.<kbd>chr</kbd>(<var>3</var>).$color.<var>'$1'</var>);
  } <kbd>else</kbd> {
    $server-&gt;command(<var>'/^format action_public {pubaction $0}$1'</var>);
  }
}

<kbd>sub</kbd> cmd_color {
  <kbd>my</kbd> ($data, $server, $witem) = @_;
  <kbd>my</kbd> ($op, $nick, $color) = split <var>" "</var>, $data;

  $op = <kbd>lc</kbd> $op;

  <kbd>if</kbd> (!$op || $op <kbd>eq</kbd> <var>"help"</var>) {
    Irssi::print (<var>"Supported commands: 
    preview (list possible colors and their codes)
    list (show current entries in saved_colors)
    set &lt;nick&gt; <color> (associate a color to a nick)
    rset &lt;regex&gt; <color> (colorize messages matching a regex)
    clear &lt;nick&gt; (delete color associated to nick)
    rclear &lt;regex&gt; (delete color associated to regex)
    save (save colorsettings to saved_colors file)"</var>);
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"save"</var>) {
    save_colors;
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"set"</var>) {
    <kbd>if</kbd> (!$nick) {
      Irssi::print (<var>"Nick not given"</var>);
    } <kbd>elsif</kbd> (!$color) {
      Irssi::print (<var>"Color not given"</var>);
    } <kbd>elsif</kbd> ($color &lt; <var>2</var> || $color &gt; <var>14</var>) {
      Irssi::print (<var>"Color must be between 2 and 14 inclusive"</var>);
    } <kbd>else</kbd> {
      $saved_colors{$nick} = $color;
    }
    Irssi::print (<var>"Added "</var>.<kbd>chr</kbd> (<var>3</var>) . <var>"$saved_colors{$nick}$nick"</var> .
                           <kbd>chr</kbd> (<var>3</var>) . <var>"1 ($saved_colors{$nick})"</var>);
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"rset"</var>) {
    <kbd>if</kbd> (!$nick) {
      Irssi::print (<var>"Regex not given"</var>);
    } <kbd>elsif</kbd> (!$color) {
      Irssi::print (<var>"Color not given"</var>);
    } <kbd>elsif</kbd> ($color &lt; <var>2</var> || $color &gt; <var>14</var>) {
      Irssi::print (<var>"Color must be between 2 and 14 inclusive"</var>);
    } <kbd>else</kbd> {
      $saved_regex_colors{$nick} = $color;
    }
    Irssi::print (<var>"Added "</var>.<kbd>chr</kbd> (<var>3</var>) . <var>"$saved_regex_colors{$nick}$nick"</var> .
                           <kbd>chr</kbd> (<var>3</var>) . <var>"1 ($saved_regex_colors{$nick})"</var>);
  } <kbd>elsif</kbd> ($op <kbd>eq </kbd><var>"clear"</var>) {
    <kbd>if</kbd> (!$nick) {
      Irssi::print (<var>"Nick not given"</var>);
    } <kbd>else</kbd> {
      <kbd>delete</kbd> ($saved_colors{$nick});
    }
    Irssi::print (<var>"Cleared "</var>.$nick);
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"rclear"</var>) {
    <kbd>if</kbd> (!$nick) {
      Irssi::print (<var>"Regex not given"</var>);
    } <kbd>else</kbd> {
      <kbd>delete</kbd> ($saved_regex_colors{$nick});
    }
    Irssi::print (<var>"Cleared "</var>.$nick);
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"list"</var>) {
    Irssi::print (<var>"\nSaved colors:"</var>);
    <kbd>foreach my</kbd> $nick (<kbd>keys</kbd> %saved_colors) {
      Irssi::print (<var>"Nick: "</var>.<kbd>chr</kbd> (<var>3</var>) . <var>"$saved_colors{$nick}$nick"</var> .
		             <kbd>chr</kbd> (<var>3</var>) . <var>"1 ($saved_colors{$nick})"</var>);
    }
    <kbd>foreach my</kbd> $r (<kbd>keys</kbd> %saved_regex_colors) {
      Irssi::print (<var>"Regex: "</var>.<kbd>chr</kbd> (<var>3</var>) . <var>"$saved_regex_colors{$r}$r"</var> .
                              <kbd>chr</kbd> (<var>3</var>) . <var>"1 ($saved_regex_colors{$r})"</var>);
    }
  } <kbd>elsif</kbd> ($op <kbd>eq</kbd> <var>"preview"</var>) {
    Irssi::print (<var>"\nAvailable colors:"</var>);
    <kbd>foreach my</kbd> $i (<var>2</var>..<var>14</var>) {
      Irssi::print (<kbd>chr</kbd> (<var>3</var>) . <var>"$i"</var> . <var>"Color #$i"</var>);
    }
  }
}

load_colors;

Irssi::command_bind(<var>'color'</var>, <var>'cmd_color'</var>);

Irssi::signal_add(<var>'message public'</var>, <var>'sig_public'</var>);
Irssi::signal_add(<var>'message irc action'</var>, <var>'sig_action'</var>);
Irssi::signal_add(<var>'event nick'</var>, <var>'sig_nick'</var>);</pre>
</samp>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Feb 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Audio Captchas in PHP</title>
 <link href="https://imrannazar.com/articles/php-audio-captcha" rel="alternate" type="text/html" title="Audio Captchas in PHP" />
 <id>https://imrannazar.com/articles/php-audio-captcha</id>
 <summary>The major compromise made when a website uses Captcha images is that between accessibility and security; those with bad eyesight or colour-blindness may have trouble viewing a Captcha image. One way around that is to provide an MP3 download option for the Captcha text, which gives another path of accessibility to the process. This article looks at how an audio Captcha can be generated, using common tools.</summary>
 <category term="Articles" />
 <published>Sat, 09 Jan 2010 17:43:48 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One of the problems most often cited with a Captcha-based submission verification system is the lack of accessible options; a plain-text alternative can't be provided, for the simple reason that it gives an easy route to circumvent the Captcha and thus defeat the point of putting such a system in place.</p>
<p>Any alternative means of finding out what the Captcha image shows must be accessible for people who can't view the image, while also presenting a level of difficulty for automated and spam submissions; an option that meets both of these criteria is the audio Captcha.</p>
<h2>The concept</h2>
<p>The idea behind an audio Captcha is simple: in addition to providing the Captcha image on-screen, a sound file representing the image is made available. This caters for most users who would otherwise be unable to enter the Captcha text. This sound file can be a simple RIFF wave file, but is more often encoded into a speech codec or the ubiquitous MP3 format.</p>
<p>In this article, I'll be looking at the implementation of a simple MP3 audio Captcha, which takes a short string of a few characters and creates a sound file. I'll assume for this article that it's only made up of lowercase letters; there are no digits or uppercase letters, and no punctuation, in order to keep things at a minimal level. The audio Captcha algorithm is based on a series of sound files, each representing one letter, which can then be concatenated into a representation of the whole string.</p>
<figure class="invertable">
 <img src="/content/img/audio-captcha-algorithm.png" alt="The audio Captcha algorithm">
 <figcaption>Figure 1: The concatenation algorithm</figcaption>
</figure>
<p>In the ideal case, it would be simple to take the contents of each file and run them together into one large file, by writing out the contents of the files one after the other. This would be a trivial concatenation process, but will unfortunately not work. For the reason behind that, it's important to look at what makes up a RIFF wave file.</p>
<h2>The RIFF file format</h2>
<p>A RIFF wave file is more than a basic recording of the digitised waveform; in addition to the waveform data, metadata is attached regarding the size of the data and its origin.</p>
<figure>
 <table>
  <tr><th style="width:100px">Byte 1</th><th style="width:100px">Byte 2</th><th style="width:100px">Byte 3</th><th style="width:100px">Byte 4</th></tr>
  <tr><td colspan="4">Chunk header: "RIFF"</td></tr>
  <tr><td colspan="4">RIFF chunk size (file size-8)</td></tr>
  <tr><td colspan="4">Chunk header: "WAVE"</td></tr>
  <tr><td colspan="4"><strong>Subchunk header: "fmt "</strong></td></tr>
  <tr><td colspan="4">Format chunk size</td></tr>
  <tr><td colspan="2">Format (1=PCM)</td><td colspan="2">Channel count</td></tr>
  <tr><td colspan="4">Sampling rate (Hz)</td></tr>
  <tr><td colspan="4">Bytes per second</td></tr>
  <tr><td colspan="2">Block alignment value</td><td colspan="2">Bits per sample</td></tr>
  <tr><td colspan="4"><strong>Subchunk header: "data"</strong></td></tr>
  <tr><td colspan="4">Data size</td></tr>
  <tr><td colspan="4" rowspan="2">File data</td></tr>
  <tr></tr>
 </table>
 <figcaption>Table 1: RIFF wave file format</figcaption>
</figure>
<p>The table above shows the format of the simplest RIFF wave file. The format is capable of holding information about wave files intended for MIDI samplers, cue points for mixing, and various other additions; most wave files will not contain these, and will simply be a record of the waveform data with a header attached.</p>
<p>As can be seen, the wave file specifies not only the length of the digitised waveform, but also its sampling rate and channel count. A telephone-level wave file can easily be distinguished from a CD-quality file, by simply checking the sampling rate; in a similar manner, stereo waveform files and monoscopic files can be differentiated. The provision of this metadata about the file is the reason for the attachment of the header, since otherwise a sound player application would have no idea of the process for playing the sound file.</p>
<p>Unfortunately, this means that simple concatenation of two RIFF files won't result in a longer RIFF file. A sound player will read the headers at the start of the file, which indicate the length of the first segment to be concatenated, and play that segment; at this point, a reasonable player will deduce that the end of file has been reached, since its record of played samples is the same as the number indicated in the file header, and won't play any more of the file.</p>
<p>The solution to this problem is to use a more complex concatenation: instead of simply throwing the files together, they will need to be run through an external sound processor.</p>
<h2>External sound processors</h2>
<p>The <code>sox</code> command is a simple interface to an audio concatenation and processing tool, which can be used for this audio Captcha. If each letter's wave file is passed into sox, a wave file can be output consisting of all the input files together, with an updated format header containing the total data size and overall sampling rates. An example invocation would run as follows:</p>
<samp>
 <h3>Invocation of sox: An example concatenation</h3>
 <pre>sox a.wav x.wav m.wav b.wav -t .wav axmb.wav</pre>
</samp>
<p>Since each letter is contained in its own wave file, it's a trivial matter to break up the Captcha text string and build a command line for <code>sox</code> to use. The following example assumes that the Captcha script is written in PHP, and the text is held in the session data after generation.</p>
<samp>
 <h3>Building the concatenated wave file</h3>
 <pre>$parts = <kbd>array</kbd>();
<kbd>for</kbd>($i = <var>0</var>; $i &lt; <kbd>strlen</kbd>($_SESSION[<var>'captcha'</var>]); $i++)
    $parts[] = $_SESSION[<var>'captcha'</var>][$i] . <var>'.wav'</var>;

<kbd>exec</kbd>(<kbd>sprintf</kbd>(<var>'sox %s -t .wav %s.wav'</var>, <kbd>join</kbd>(<var>' '</var>, $parts), $_SESSION[<var>'captcha'</var>]));</pre>
</samp>
<p>What this doesn't do is generate an MP3 representing the Captcha text; for that, an MP3 encoder is required. <code>lame</code> allows for the encoding of MP3s at various sampling rates, but will normally take its sampling information from the input file. Since, as detailed above, a wave file contains detailed information about sampling and formatting, <code>lame</code> is able to use this to generate an MP3 file.</p>
<p>The example below is a slight modification of the <code>sox</code> invocation above, in order to pipe the output to <code>lame</code> and encode an MP3 file, and then to serve the MP3 out as a downloadable file.</p>
<samp>
 <h3>Building a Captcha MP3</h3>
 <pre>$parts = <kbd>array</kbd>();
$c = $_SESSION[<var>'captcha'</var>];
<kbd>for</kbd>($i = <var>0</var>; $i &lt; <kbd>strlen</kbd>($c); $i++)
    $parts[] = $c[$i] . <var>'.wav'</var>;

<kbd>exec</kbd>(<kbd>sprintf</kbd>(<var>'sox %s -t .wav - | lame - %s.mp3'</var>, <kbd>join</kbd>(<var>' '</var>, $parts), $c));

<kbd>header</kbd>(<var>'Content-type: audio/mpeg'</var>);
<kbd>header</kbd>(<var>'Content-length: '</var>.<kbd>filesize</kbd>(<var>"</var>{$c}<var>.mp3"</var>));
<kbd>header</kbd>(<var>'Content-disposition: attachment; name="'</var>.$c.<var>'.mp3"'</var>);
<kbd>passthru</kbd>(<var>"</var>{$c}<var>.mp3"</var>);</pre>
</samp>
<p>An example of this script's usage in a Captcha would be as follows.</p>
<figure>
 <img src="/content/img/audio-captcha-pqjryd.gif" alt="Captcha image">
 <a href="/content/img/audio-captcha-pqjryd.mp3"><img src="/content/img/audio-captcha-speaker.png" alt="Download MP3"></a>
 <figcaption>Figure 2: Example Captcha with audio download option</figcaption>
</figure>
<h2>Possible enhancements</h2>
<p>In the above example, clearly voiced phrases have been used for the constituent letters of the audio Captcha. This provides a good level of accessibility, but compromises the security of the audio Captcha: any automatic circumventions will easily be able to work out the letters that make up the audio file. One solution to this is to overlay a level of noise on the audio file, to provide some level of obfuscation to the output; in addition to this, periods of silence can be inserted between the letter waveforms, making the output less regular.</p>
<p>Another enhancement that can be made to the audio Captcha output is to provide more formats for the file. At present, the audio Captcha is generated in RIFF wave and MP3 formats; provision for Windows audio and Ogg formats would allow for more widespread usage of the output file.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jan 2010.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Binary-Coded Decimal Addition on Atmel AVR</title>
 <link href="https://imrannazar.com/articles/avr-bcd-addition" rel="alternate" type="text/html" title="Binary-Coded Decimal Addition on Atmel AVR" />
 <id>https://imrannazar.com/articles/avr-bcd-addition</id>
 <summary>The AVR instruction set manual mentions binary-coded decimal exactly once, and provides no instructions for easily working with BCD values, despite the utility of BCD in embedded applications. This article explores the issues involved in working with BCD values, especially in incrementing and adding such values, and introduces an algorithm for resolving the discrepancies that arise.</summary>
 <category term="Articles" />
 <published>Sat, 19 Dec 2009 18:04:45 +0000</published>
 <content type="text/html"><![CDATA[
   <h2>UPDATE: Nov 2021</h2>
<p>Petter K&auml;llstr&ouml;m emailed me, saying that there are a couple of weirdnesses and inefficiencies in the implementation given at the bottom of this article, and provided alternative code as follows:</p>
<samp>
 <h3>Petter's more better implementation</h3>
 <pre><s>-- input = r18, C and H flag</s>
<s>-- output = r18 and C flag</s>
DAA:
  <kbd>push</kbd> r19
  <kbd>in</kbd>   r19, SREG    <s>; Let r19 contain the SREG</s>
  <kbd>cpi</kbd>  r18, $9A     <s>; Set C flag in r19 if r18 &gt;= 9A, and H flag in SREG if lower nibble is &lt; 10</s>
  <kbd>brlo</kbd> DAA_endif
  <kbd>sbr</kbd>  r19, (1&lt;&lt;SREG_C)
DAA_endif:
  <kbd>sbrs</kbd> r19, SREG_H  <s>; If input H flag was set, then skip the H-flag test</s>
  <kbd>brhs</kbd> DAA_hi       <s>;   If H indicate lower nibble is &lt; 10, then jump over...</s>
  <kbd>subi</kbd> r18, -$06    <s>; adjust (adjust if r19.H-flag set, or if lower nibble &gt;= 10)</s>
DAA_hi:
  <kbd>sbrc</kbd> r19, SREG_C  <s>; If output C=1</s>
  <kbd>subi</kbd> r18, -$60    <s>;   ...adjust</s>
  <kbd>out</kbd>  SREG, r19
  <kbd>pop</kbd>  r19
  <kbd>ret</kbd></pre>
</samp>
<hr>
<h2>Back to our previously scheduled article:</h2>
<p>The Atmel AVR series of microcontrollers can be used in a wide variety of applications, from radios right through to inkjet printers, but a popular application in hobbyist projects is for digital clocks and counters. There are two main portions to any clock or counter program: a piece of code to increment the internal counter, and another piece of code to format and output the counter on a display.</p>
<p>A problem arises where these two portions of code need to interact. If one of these tasks is made less taxing for the microcontroller, the other is made more complicated; as a result, there are two prevailing schools of thought on how to achieve this interaction.</p>
<ul>
 <li><strong>Easier to calculate:</strong> A simple binary number can be held by the controller, which is very easy to increment. This forces the display code to iteratively divide the number down by ten, in order to extract the digits for display.</li>
 <li><strong>Easier to display:</strong> A packed binary-coded decimal (BCD) number can be used instead to hold the counter; this simplifies the display logic, but incrementing the number requires an adjustment process to be run in order to correctly align the BCD segments.</li>
</ul>
<p>This article will examine the implications of choosing the second method: the use of a BCD number to hold the counter.</p>
<h2>Packed BCD digits</h2>
<p>The concept behind BCD is a simple one: instead of using a byte to represent any value between 0 and 255, a byte is used to represent the decimal digits only: 0 to 9. This allows for each segment of a multiple-digit display to be tied directly to a byte in the number to show, which greatly simplifies the logic behind showing the number.</p>
<figure class="invertable">
 <img src="/content/img/avr-daa-bcd.png" alt="Byte-wise BCD">
 <figcaption>Figure 1: Byte-wise (full) BCD display</figcaption>
</figure>
<p>The disadvantage of using a full byte to represent each digit is the waste produced: over 95% of the usable range of numbers in a byte is lost, and a large number of bytes have to be stored for a number of significant size. In a microcontroller environment, where memory space is often at such a premium that one extra byte is significant, this wastage is simply untenable.</p>
<p>An alternative scheme is to use each nybble of a byte to store a BCD digit: in this manner, two digits can be stored inside a byte, increasing the range of values available for storage ten-fold. The code required to pull out digits for display is still very straightforward, since simple boolean operations will yield the required result.</p>
<figure class="invertable">
 <img src="/content/img/avr-daa-pbcd.png" alt="Packed BCD">
 <figcaption>Figure 2: Packed BCD display</figcaption>
</figure>
<p>A packed BCD number can be held in half the space of the equivalent full-BCD value, and is a viable compromise between the full range of binary numbers and the ease of display of full-BCD. In addition to this, packed BCD (hereafter referred to as simply "BCD") can be trivially conceptualised, through conversion to hexadecimal: as an example, the BCD value <code>0x93</code> represents decimal 93.</p>
<h2>BCD addition: the problem</h2>
<p>Using BCD to display a decimal number may simplify the display logic a great deal compared to the alternative, but a problem arises when calculations need to be done on the numbers. A microcontroller, much like any other computer of the modern age, is a binary machine with a binary arithmetic unit: it has no understanding of BCD, and will dutifully treat each number coming into it as a plain binary number.</p>
<samp>
 <h3>Example additions of BCD numbers</h3>
 <pre>0x15 + 0x03 = 0x18
0x72 + 0x07 = 0x79
0x38 + 0x02 = <var>0x3A</var></pre>
</samp>
<p>It is in additions that cause a carry between digits that the problem appears. In the above example, the BCD numbers <code>0x38</code> and <code>0x02</code> should add to <code>0x40</code>, but the addition has operated instead on the plain numbers and produced the wrong answer. What is required is a method of adjusting the value after addition, to account for the fact that the values being operated on are BCD.</p>
<p>The Intel IA-32 series of microprocessors contains such a method as part of the base instruction set: Decimal Adjust after Addition (DAA). If this instruction is run after an addition, the result stored in the accumulator will be adjusted.</p>
<samp>
 <h3>DAA usage on Intel x86</h3>
 <pre><kbd>mov</kbd> al, <var>38h</var>
<kbd>add</kbd> al, <var>03h</var>

<s>; At this point, al = 0x3B</s>
<kbd>daa</kbd>
<s>; al = 0x41</s></pre>
</samp>
<p>The Atmel AVR doesn't contain such a convenient instruction as DAA, but the algorithm behind the DAA instruction is documented as part of the Intel IA-32 Reference manual, and is simple both to understand and to re-implement.</p>
<h2>The decimal adjustment algorithm</h2>
<p>DAA will adjust a BCD value that has had a carry occur between digits. There are two situations where this applies:</p>
<ul>
 <li><strong>BCD carry:</strong> This occurs in a situation much like the one detailed above, where a result is too large to fit into a BCD digit but is still large enough for a binary nybble. Checking for this is simple: if the nybble has a value over 9, BCD carry has occurred.</li>
 <li><strong>Binary carry:</strong> This will happen if a BCD digit addition result is not just larger than a BCD digit, but larger than 15: the nybble containing the BCD digit will itself carry, and end up with a value lower than 9. Results of this type would not be caught by the check for values over 9.</li>
</ul>
<p>Most processor architectures maintain a status flag denoting when a byte has carried past its maximum value; many architectures also maintain a <em>half-carry</em> flag, that is set when the lower nybble of a byte carries into the upper nybble. The half-carry flag will be set by a BCD addition that causes a binary carry in the lower digit, so checking for this will satisfy the other half of the DAA check.</p>
<p>If the DAA check finds a digit that needs adjusting, the fix is simple: a further addition onto the nybble in question.</p>
<samp>
 <h3>Adjustment of a nybble</h3>
 <pre>0x08 + 0x03 = 0x0B <s>; Should be 0x11</s>
0x09 + 0x05 = 0x0E <s>; Should be 0x14</s>
0x09 + 0x08 = 0x11 <s>; Should be 0x17</s></pre>
</samp>
<p>In every case, the value is six away from where it should be, so the adjustment adds six to bring the value back into BCD. Applying this process to both nybbles yields the final DAA algorithm.</p>
<samp>
 <h3>2-digit BCD decimal adjustment after addition</h3>
 <pre>OLD_value = Value
OLD_carry = Carry from addition

<s># Check lower nybble</s>
IF (Half-carry set by addition) OR (Lower nybble of Value &gt; 9)
    ADD 6 to Value
FI

<s># Check upper nybble
# Upper nybble will be over 9 if original Value was over 0x99</s>
IF(OLD_carry) OR (OLD_value &gt; 0x99)
    ADD 0x60 to Value
    Carry = 1 <s># BCD value carry occurred</s>
ELSE
    Carry = 0
FI</pre>    
</samp>
<p>The DAA algoithm sets the carry flag based on whether the upper nybble overflowed; this allows DAA to be used on BCD values across multiple bytes, by employing addition-with-carry on any higher denominations.</p>
<h2>Implementing DAA on AVR</h2>
<p>Translating DAA from the algorithm detailed above results in the following AVR code.</p>
<samp>
 <h3>AVR implementation of DAA</h3>
 <pre><s>; Parameters: R16 = value to adjust
; Returns: R16 = Adjusted value
;          Carry flag set if adjustment caused BCD carry</s>
DAA:
    <kbd>push</kbd> r16
    <kbd>push</kbd> r17
    <kbd>push</kbd> r18
    <kbd>push</kbd> r19

    <kbd>push</kbd> r16
    <kbd>mov</kbd> r17, r16
    <kbd>mov</kbd> r18, r16
    <kbd>in</kbd> r19, <var>SREG</var>
    <kbd>andi</kbd> r19, (<var>1</var>&lt;&lt;<var>SREG_C</var>)

    <kbd>clc</kbd>
    <kbd>brhs</kbd> DAA_adjlo
    <kbd>andi</kbd> r17, <var>0x0F</var>
    <kbd>cpi</kbd> r17, <var>10</var>
    <kbd>brlo</kbd> DAA_hi
DAA_adjlo:
    <kbd>ldi</kbd> r17, <var>6</var>
    <kbd>add</kbd> r16, r17

DAA_hi:
    <kbd>tst</kbd> r19
    <kbd>brne</kbd> DAA_adjhi
    <kbd>pop</kbd> r17
    <kbd>cpi</kbd> r17, <var>0x9A</var>
    <kbd>brlo</kbd> DAA_nadjhi
DAA_adjhi:
    <kbd>ldi</kbd> r17, <var>0x60</var>
    <kbd>add</kbd> r16, r17
    <kbd>sec</kbd>
    <kbd>rjmp</kbd> DAA_end
DAA_nadjhi:
    <kbd>clc</kbd>

DAA_end:
    <kbd>pop</kbd> r19
    <kbd>pop</kbd> r18
    <kbd>pop</kbd> r17
    <kbd>pop</kbd> r16
    <kbd>ret</kbd></pre>
</samp>
<p>Usage of the DAA routine for a two-byte BCD value stored in SRAM, would work like this:</p>
<samp>
 <h3>Calling DAA across two BCD bytes</h3>
 <pre><s>; Add BCD 57 to the value stored at SRAM:0x100</s>
    <kbd>ldi</kbd> xl, <var>0x00</var>
    <kbd>ldi</kbd> xh, <var>0x01</var>

<s>; Read in low byte, add 57 BCD, and store</s>
    <kbd>ld</kbd> r16, x
    <kbd>ldi</kbd> r17, <var>0x57</var>
    <kbd>add</kbd> r16, r17
    <kbd>call</kbd> DAA
    <kbd>st</kbd> x+, r16

<s>; Read in high byte, add carry from low byte, and store</s>
    <kbd>ld</kbd> r16, x
    <kbd>clr</kbd> r17
    <kbd>adc</kbd> r16, r17
    <kbd>call</kbd> DAA
    <kbd>st</kbd> x, r16</pre>
</samp>
<h2>Other decimal adjustment routines</h2>
<p>The Intel IA-32 instruction set also contains a routine for decimal adjustment after subtraction, which operates in a slightly different manner to that detailed above. Development of such a routine for AVR is beyond the scope of this article, but can be done in a similar vein to DAA by pulling the algorithm from the IA-32 Reference manual.</p>
<p>If this routine proves useful, or if you come across any bugs with its operation, please feel free to let me know.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Dec 2009. Code released into the public domain.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Gameboy Z80 Opcode Map</title>
 <link href="https://imrannazar.com/articles/gameboy-z80-opcode-map" rel="alternate" type="text/html" title="Gameboy Z80 Opcode Map" />
 <id>https://imrannazar.com/articles/gameboy-z80-opcode-map</id>
 <summary>The CPU used by the Nintendo GameBoy is a specially modified version of the Z80, with various functions removed to make the CPU cheaper to manufacture. Documentation for this CPU is often lacking; the most common opcode maps are written down as a standard Z80 map with addenda for the Nintendo modifications. This opcode map collates the references into a coherent opcode map for the Nintendo GB-Z80.</summary>
 <category term="Articles" />
 <published>Mon, 16 Nov 2009 20:56:50 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The following is a full opcode map of instructions for the Nintendo-spec modified Z80 included in the GameBoy CPU.</p>
<p><em>Updated: [2010-07-28] Details added for SWAP, [2010-07-29] XOR n reinstated</em></p>
<figure class="compact">
 <table>
  <thead>
   <tr><th></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th></tr>
  </thead>
  <tbody>
   <tr>
    <td><strong>0x</strong></td>
    <td><abbr title="No Operation">NOP</abbr></td>
    <td><abbr title="Load 16-bit immediate into BC">LD BC,nn</abbr></td>
    <td><abbr title="Save A to address pointed by BC">LD (BC),A</abbr></td>
    <td><abbr title="Increment 16-bit BC">INC BC</abbr></td>
    <td><abbr title="Increment B">INC B</abbr></td>
    <td><abbr title="Decrement B">DEC B</abbr></td>
    <td><abbr title="Load 8-bit immediate into B">LD B,n</abbr></td>
    <td><abbr title="Rotate A left with carry">RLC A</abbr></td>
    <td><abbr title="Save SP to given address">LD (nn),SP</abbr></td>
    <td><abbr title="Add 16-bit BC to HL">ADD HL,BC</abbr></td>
    <td><abbr title="Load A from address pointed to by BC">LD A,(BC)</abbr></td>
    <td><abbr title="Decrement 16-bit BC">DEC BC</abbr></td>
    <td><abbr title="Increment C">INC C</abbr></td>
    <td><abbr title="Decrement C">DEC C</abbr></td>
    <td><abbr title="Load 8-bit immediate into C">LD C,n</abbr></td>
    <td><abbr title="Rotate A right with carry">RRC A</abbr></td>
   </tr>
   <tr>
    <td><strong>1x</strong></td>
    <td><abbr title="Stop processor">STOP</abbr></td>
    <td><abbr title="Load 16-bit immediate into DE">LD DE,nn</abbr></td>
    <td><abbr title="Save A to address pointed by DE">LD (DE),A</abbr></td>
    <td><abbr title="Increment 16-bit DE">INC DE</abbr></td>
    <td><abbr title="Increment D">INC D</abbr></td>
    <td><abbr title="Decrement D">DEC D</abbr></td>
    <td><abbr title="Load 8-bit immediate into D">LD D,n</abbr></td>
    <td><abbr title="Rotate A left">RL A</abbr></td>
    <td><abbr title="Relative jump by signed immediate">JR n</abbr></td>
    <td><abbr title="Add 16-bit DE to HL">ADD HL,DE</abbr></td>
    <td><abbr title="Load A from address pointed to by DE">LD A,(DE)</abbr></td>
    <td><abbr title="Decrement 16-bit DE">DEC DE</abbr></td>
    <td><abbr title="Increment E">INC E</abbr></td>
    <td><abbr title="Decrement E">DEC E</abbr></td>
    <td><abbr title="Load 8-bit immediate into E">LD E,n</abbr></td>
    <td><abbr title="Rotate A right">RR A</abbr></td>
   </tr>
   <tr>
    <td><strong>2x</strong></td>
    <td><abbr title="Relative jump by signed immediate if last result was not zero">JR NZ,n</abbr></td>
    <td><abbr title="Load 16-bit immediate into HL">LD HL,nn</abbr></td>
    <td><abbr title="Save A to address pointed by HL, and increment HL">LDI (HL),A</abbr></td>
    <td><abbr title="Increment 16-bit HL">INC HL</abbr></td>
    <td><abbr title="Increment H">INC H</abbr></td>
    <td><abbr title="Decrement H">DEC H</abbr></td>
    <td><abbr title="Load 8-bit immediate into H">LD H,n</abbr></td>
    <td><abbr title="Adjust A for BCD addition">DAA</abbr></td>
    <td><abbr title="Relative jump by signed immediate if last result was zero">JR Z,n</abbr></td>
    <td><abbr title="Add 16-bit HL to HL">ADD HL,HL</abbr></td>
    <td><abbr title="Load A from address pointed to by HL, and increment HL">LDI A,(HL)</abbr></td>
    <td><abbr title="Decrement 16-bit HL">DEC HL</abbr></td>
    <td><abbr title="Increment L">INC L</abbr></td>
    <td><abbr title="Decrement L">DEC L</abbr></td>
    <td><abbr title="Load 8-bit immediate into L">LD L,n</abbr></td>
    <td><abbr title="Complement (logical NOT) on A">CPL</abbr></td>
   </tr>
   <tr>
    <td><strong>3x</strong></td>
    <td><abbr title="Relative jump by signed immediate if last result caused no carry">JR NC,n</abbr></td>
    <td><abbr title="Load 16-bit immediate into SP">LD SP,nn</abbr></td>
    <td><abbr title="Save A to address pointed by HL, and decrement HL">LDD (HL),A</abbr></td>
    <td><abbr title="Increment 16-bit HL">INC SP</abbr></td>
    <td><abbr title="Increment value pointed by HL">INC (HL)</abbr></td>
    <td><abbr title="Decrement value pointed by HL">DEC (HL)</abbr></td>
    <td><abbr title="Load 8-bit immediate into address pointed by HL">LD (HL),n</abbr></td>
    <td><abbr title="Set carry flag">SCF</abbr></td>
    <td><abbr title="Relative jump by signed immediate if last result caused carry">JR C,n</abbr></td>
    <td><abbr title="Add 16-bit SP to HL">ADD HL,SP</abbr></td>
    <td><abbr title="Load A from address pointed to by HL, and decrement HL">LDD A,(HL)</abbr></td>
    <td><abbr title="Decrement 16-bit SP">DEC SP</abbr></td>
    <td><abbr title="Increment A">INC A</abbr></td>
    <td><abbr title="Decrement A">DEC A</abbr></td>
    <td><abbr title="Load 8-bit immediate into A">LD A,n</abbr></td>
    <td><abbr title="Clear carry flag">CCF</abbr></td>
   </tr>
   <tr>
    <td><strong>4x</strong></td>
    <td><abbr title="Copy B to B">LD B,B</abbr></td>
    <td><abbr title="Copy C to B">LD B,C</abbr></td>
    <td><abbr title="Copy D to B">LD B,D</abbr></td>
    <td><abbr title="Copy E to B">LD B,E</abbr></td>
    <td><abbr title="Copy H to B">LD B,H</abbr></td>
    <td><abbr title="Copy L to B">LD B,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to B">LD B,(HL)</abbr></td>
    <td><abbr title="Copy A to B">LD B,A</abbr></td>
    <td><abbr title="Copy B to C">LD C,B</abbr></td>
    <td><abbr title="Copy C to C">LD C,C</abbr></td>
    <td><abbr title="Copy D to C">LD C,D</abbr></td>
    <td><abbr title="Copy E to C">LD C,E</abbr></td>
    <td><abbr title="Copy H to C">LD C,H</abbr></td>
    <td><abbr title="Copy L to C">LD C,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to C">LD C,(HL)</abbr></td>
    <td><abbr title="Copy A to C">LD C,A</abbr></td>
   </tr> 
   <tr>
    <td><strong>5x</strong></td>
    <td><abbr title="Copy B to D">LD D,B</abbr></td>
    <td><abbr title="Copy C to D">LD D,C</abbr></td>
    <td><abbr title="Copy D to D">LD D,D</abbr></td>
    <td><abbr title="Copy E to D">LD D,E</abbr></td>
    <td><abbr title="Copy H to D">LD D,H</abbr></td>
    <td><abbr title="Copy L to D">LD D,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to D">LD D,(HL)</abbr></td>
    <td><abbr title="Copy A to D">LD D,A</abbr></td>
    <td><abbr title="Copy B to E">LD E,B</abbr></td>
    <td><abbr title="Copy C to E">LD E,C</abbr></td>
    <td><abbr title="Copy D to E">LD E,D</abbr></td>
    <td><abbr title="Copy E to E">LD E,E</abbr></td>
    <td><abbr title="Copy H to E">LD E,H</abbr></td>
    <td><abbr title="Copy L to E">LD E,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to E">LD E,(HL)</abbr></td>
    <td><abbr title="Copy A to E">LD E,A</abbr></td>
   </tr>
   <tr>
    <td><strong>6x</strong></td>
    <td><abbr title="Copy B to H">LD H,B</abbr></td>
    <td><abbr title="Copy C to H">LD H,C</abbr></td>
    <td><abbr title="Copy D to H">LD H,D</abbr></td>
    <td><abbr title="Copy E to H">LD H,E</abbr></td>
    <td><abbr title="Copy H to H">LD H,H</abbr></td>
    <td><abbr title="Copy L to H">LD H,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to H">LD H,(HL)</abbr></td>
    <td><abbr title="Copy A to H">LD H,A</abbr></td>
    <td><abbr title="Copy B to L">LD L,B</abbr></td>
    <td><abbr title="Copy C to L">LD L,C</abbr></td>
    <td><abbr title="Copy D to L">LD L,D</abbr></td>
    <td><abbr title="Copy E to L">LD L,E</abbr></td>
    <td><abbr title="Copy H to L">LD L,H</abbr></td>
    <td><abbr title="Copy L to L">LD L,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to L">LD L,(HL)</abbr></td>
    <td><abbr title="Copy A to L">LD L,A</abbr></td>
   </tr>
   <tr>
    <td><strong>7x</strong></td>
    <td><abbr title="Copy B to address pointed by HL">LD (HL),B</abbr></td>
    <td><abbr title="Copy C to address pointed by HL">LD (HL),C</abbr></td>
    <td><abbr title="Copy D to address pointed by HL">LD (HL),D</abbr></td>
    <td><abbr title="Copy E to address pointed by HL">LD (HL),E</abbr></td>
    <td><abbr title="Copy H to address pointed by HL">LD (HL),H</abbr></td>
    <td><abbr title="Copy L to address pointed by HL">LD (HL),L</abbr></td>
    <td><abbr title="Halt processor">HALT</abbr></td>
    <td><abbr title="Copy A to address pointed by HL">LD (HL),A</abbr></td>
    <td><abbr title="Copy B to A">LD A,B</abbr></td>
    <td><abbr title="Copy C to A">LD A,C</abbr></td>
    <td><abbr title="Copy D to A">LD A,D</abbr></td>
    <td><abbr title="Copy E to A">LD A,E</abbr></td>
    <td><abbr title="Copy H to A">LD A,H</abbr></td>
    <td><abbr title="Copy L to A">LD A,L</abbr></td>
    <td><abbr title="Copy value pointed by HL to A">LD A,(HL)</abbr></td>
    <td><abbr title="Copy A to A">LD A,A</abbr></td>
   </tr>
   <tr>
    <td><strong>8x</strong></td>
    <td><abbr title="Add B to A">ADD A,B</abbr></td>
    <td><abbr title="Add C to A">ADD A,C</abbr></td>
    <td><abbr title="Add D to A">ADD A,D</abbr></td>
    <td><abbr title="Add E to A">ADD A,E</abbr></td>
    <td><abbr title="Add H to A">ADD A,H</abbr></td>
    <td><abbr title="Add L to A">ADD A,L</abbr></td>
    <td><abbr title="Add value pointed by HL to A">ADD A,(HL)</abbr></td>
    <td><abbr title="Add A to A">ADD A,A</abbr></td>
    <td><abbr title="Add B and carry flag to A">ADC A,B</abbr></td>
    <td><abbr title="Add C and carry flag to A">ADC A,C</abbr></td>
    <td><abbr title="Add D and carry flag to A">ADC A,D</abbr></td>
    <td><abbr title="Add E and carry flag to A">ADC A,E</abbr></td>
    <td><abbr title="Add H and carry flag to A">ADC A,H</abbr></td>
    <td><abbr title="Add and carry flag L to A">ADC A,L</abbr></td>
    <td><abbr title="Add value pointed by HL and carry flag to A">ADC A,(HL)</abbr></td>
    <td><abbr title="Add A and carry flag to A">ADC A,A</abbr></td>
   </tr>
   <tr>
    <td><strong>9x</strong></td>
    <td><abbr title="Subtract B from A">SUB A,B</abbr></td>
    <td><abbr title="Subtract C from A">SUB A,C</abbr></td>
    <td><abbr title="Subtract D from A">SUB A,D</abbr></td>
    <td><abbr title="Subtract E from A">SUB A,E</abbr></td>
    <td><abbr title="Subtract H from A">SUB A,H</abbr></td>
    <td><abbr title="Subtract L from A">SUB A,L</abbr></td>
    <td><abbr title="Subtract value pointed by HL from A">SUB A,(HL)</abbr></td>
    <td><abbr title="Subtract A from A">SUB A,A</abbr></td>
    <td><abbr title="Subtract B and carry flag from A">SBC A,B</abbr></td>
    <td><abbr title="Subtract C and carry flag from A">SBC A,C</abbr></td>
    <td><abbr title="Subtract D and carry flag from A">SBC A,D</abbr></td>
    <td><abbr title="Subtract E and carry flag from A">SBC A,E</abbr></td>
    <td><abbr title="Subtract H and carry flag from A">SBC A,H</abbr></td>
    <td><abbr title="Subtract and carry flag L from A">SBC A,L</abbr></td>
    <td><abbr title="Subtract value pointed by HL and carry flag from A">SBC A,(HL)</abbr></td>
    <td><abbr title="Subtract A and carry flag from A">SBC A,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Ax</strong></td>
    <td><abbr title="Logical AND B against A">AND B</abbr></td>
    <td><abbr title="Logical AND C against A">AND C</abbr></td>
    <td><abbr title="Logical AND D against A">AND D</abbr></td>
    <td><abbr title="Logical AND E against A">AND E</abbr></td>
    <td><abbr title="Logical AND H against A">AND H</abbr></td>
    <td><abbr title="Logical AND L against A">AND L</abbr></td>
    <td><abbr title="Logical AND value pointed by HL against A">AND (HL)</abbr></td>
    <td><abbr title="Logical AND A against A">AND A</abbr></td>
    <td><abbr title="Logical XOR B against A">XOR B</abbr></td>
    <td><abbr title="Logical XOR C against A">XOR C</abbr></td>
    <td><abbr title="Logical XOR D against A">XOR D</abbr></td>
    <td><abbr title="Logical XOR E against A">XOR E</abbr></td>
    <td><abbr title="Logical XOR H against A">XOR H</abbr></td>
    <td><abbr title="Logical XOR L against A">XOR L</abbr></td>
    <td><abbr title="Logical XOR value pointed by HL against A">XOR (HL)</abbr></td>
    <td><abbr title="Logical XOR A against A">XOR A</abbr></td>
   </tr>
   <tr>
    <td><strong>Bx</strong></td>
    <td><abbr title="Logical OR B against A">OR B</abbr></td>
    <td><abbr title="Logical OR C against A">OR C</abbr></td>
    <td><abbr title="Logical OR D against A">OR D</abbr></td>
    <td><abbr title="Logical OR E against A">OR E</abbr></td>
    <td><abbr title="Logical OR H against A">OR H</abbr></td>
    <td><abbr title="Logical OR L against A">OR L</abbr></td>
    <td><abbr title="Logical OR value pointed by HL against A">OR (HL)</abbr></td>
    <td><abbr title="Logical OR A against A">OR A</abbr></td>
    <td><abbr title="Compare B against A">CP B</abbr></td>
    <td><abbr title="Compare C against A">CP C</abbr></td>
    <td><abbr title="Compare D against A">CP D</abbr></td>
    <td><abbr title="Compare E against A">CP E</abbr></td>
    <td><abbr title="Compare H against A">CP H</abbr></td>
    <td><abbr title="Compare L against A">CP L</abbr></td>
    <td><abbr title="Compare value pointed by HL against A">CP (HL)</abbr></td>
    <td><abbr title="Compare A against A">CP A</abbr></td>
   </tr>
   <tr>
    <td><strong>Cx</strong></td>
    <td><abbr title="Return if last result was not zero">RET NZ</abbr></td>
    <td><abbr title="Pop 16-bit value from stack into BC">POP BC</abbr></td>
    <td><abbr title="Absolute jump to 16-bit location if last result was not zero">JP NZ,nn</abbr></td>
    <td><abbr title="Absolute jump to 16-bit location">JP nn</abbr></td>
    <td><abbr title="Call routine at 16-bit location if last result was not zero">CALL NZ,nn</abbr></td>
    <td><abbr title="Push 16-bit BC onto stack">PUSH BC</abbr></td>
    <td><abbr title="Add 8-bit immediate to A">ADD A,n</abbr></td>
    <td><abbr title="Call routine at address 0000h">RST 0</abbr></td>
    <td><abbr title="Return if last result was zero">RET Z</abbr></td>
    <td><abbr title="Return to calling routine">RET</abbr></td>
    <td><abbr title="Absolute jump to 16-bit location if last result was zero">JP Z,nn</abbr></td>
    <td><abbr title="Extended operations (two-byte instruction code)">Ext ops</abbr></td>
    <td><abbr title="Call routine at 16-bit location if last result was zero">CALL Z,nn</abbr></td>
    <td><abbr title="Call routine at 16-bit location">CALL nn</abbr></td>
    <td><abbr title="Add 8-bit immediate and carry to A">ADC A,n</abbr></td>
    <td><abbr title="Call routine at address 0008h">RST 8</abbr></td>
   </tr>
   <tr>
    <td><strong>Dx</strong></td>
    <td><abbr title="Return if last result caused no carry">RET NC</abbr></td>
    <td><abbr title="Pop 16-bit value from stack into DE">POP DE</abbr></td>
    <td><abbr title="Absolute jump to 16-bit location if last result caused no carry">JP NC,nn</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Call routine at 16-bit location if last result caused no carry">CALL NC,nn</abbr></td>
    <td><abbr title="Push 16-bit DE onto stack">PUSH DE</abbr></td>
    <td><abbr title="Subtract 8-bit immediate from A">SUB A,n</abbr></td>
    <td><abbr title="Call routine at address 0010h">RST 10</abbr></td>
    <td><abbr title="Return if last result caused carry">RET C</abbr></td>
    <td><abbr title="Enable interrupts and return to calling routine">RETI</abbr></td>
    <td><abbr title="Absolute jump to 16-bit location if last result caused carry">JP C,nn</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Call routine at 16-bit location if last result caused carry">CALL C,nn</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Subtract 8-bit immediate and carry from A">SBC A,n</abbr></td>
    <td><abbr title="Call routine at address 0018h">RST 18</abbr></td>
   </tr>
   <tr>
    <td><strong>Ex</strong></td>
    <td><abbr title="Save A at address pointed to by (FF00h + 8-bit immediate)">LDH (n),A</abbr></td>
    <td><abbr title="Pop 16-bit value from stack into HL">POP HL</abbr></td>
    <td><abbr title="Save A at address pointed to by (FF00h + C)">LDH (C),A</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Push 16-bit HL onto stack">PUSH HL</abbr></td>
    <td><abbr title="Logical AND 8-bit immediate against A">AND n</abbr></td>
    <td><abbr title="Call routine at address 0020h">RST 20</abbr></td>
    <td><abbr title="Add signed 8-bit immediate to SP">ADD SP,d</abbr></td>
    <td><abbr title="Jump to 16-bit value pointed by HL">JP (HL)</abbr></td>
    <td><abbr title="Save A at given 16-bit address">LD (nn),A</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Logical XOR 8-bit immediate against A">XOR n</abbr></td>
    <td><abbr title="Call routine at address 0028h">RST 28</abbr></td>
   </tr>
   <tr>
    <td><strong>Fx</strong></td>
    <td><abbr title="Load A from address pointed to by (FF00h + 8-bit immediate)">LDH A,(n)</abbr></td>
    <td><abbr title="Pop 16-bit value from stack into AF">POP AF</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="DIsable interrupts">DI</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Push 16-bit AF onto stack">PUSH AF</abbr></td>
    <td><abbr title="Logical OR 8-bit immediate against A">OR n</abbr></td>
    <td><abbr title="Call routine at address 0030h">RST 30</abbr></td>
    <td><abbr title="Add signed 8-bit immediate to SP and save result in HL">LDHL SP,d</abbr></td>
    <td><abbr title="Copy HL to SP">LD SP,HL</abbr></td>
    <td><abbr title="Load A from given 16-bit address">LD A,(nn)</abbr></td>
    <td><abbr title="Enable interrupts">EI</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Operation removed in this CPU">XX</abbr></td>
    <td><abbr title="Compare 8-bit immediate against A">CP n</abbr></td>
    <td><abbr title="Call routine at address 0038h">RST 38</abbr></td>
   </tr>
  </tbody>
 </table>
 <figcaption>Table 1: Base opcode map</figcaption>
</figure>
<figure class="compact">
 <table>
  <thead>
   <tr><th></th><th>0</th><th>1</th><th>2</th><th>3</th><th>4</th><th>5</th><th>6</th><th>7</th><th>8</th><th>9</th><th>A</th><th>B</th><th>C</th><th>D</th><th>E</th><th>F</th></tr>
  </thead>
  <tbody>
   <tr>
    <td><strong>0x</strong></td>
    <td><abbr title="Rotate B left with carry">RLC B</abbr></td>
    <td><abbr title="Rotate C left with carry">RLC C</abbr></td>
    <td><abbr title="Rotate D left with carry">RLC D</abbr></td>
    <td><abbr title="Rotate E left with carry">RLC E</abbr></td>
    <td><abbr title="Rotate H left with carry">RLC H</abbr></td>
    <td><abbr title="Rotate L left with carry">RLC L</abbr></td>
    <td><abbr title="Rotate value pointed by HL left with carry">RLC (HL)</abbr></td>
    <td><abbr title="Rotate A left with carry">RLC A</abbr></td>
    <td><abbr title="Rotate B right with carry">RRC B</abbr></td>
    <td><abbr title="Rotate C right with carry">RRC C</abbr></td>
    <td><abbr title="Rotate D right with carry">RRC D</abbr></td>
    <td><abbr title="Rotate E right with carry">RRC E</abbr></td>
    <td><abbr title="Rotate H right with carry">RRC H</abbr></td>
    <td><abbr title="Rotate L right with carry">RRC L</abbr></td>
    <td><abbr title="Rotate value pointed by HL right with carry">RRC (HL)</abbr></td>
    <td><abbr title="Rotate A right with carry">RRC A</abbr></td>
   </tr>
   <tr>
    <td><strong>1x</strong></td>
    <td><abbr title="Rotate B left">RL B</abbr></td>
    <td><abbr title="Rotate C left">RL C</abbr></td>
    <td><abbr title="Rotate D left">RL D</abbr></td>
    <td><abbr title="Rotate E left">RL E</abbr></td>
    <td><abbr title="Rotate H left">RL H</abbr></td>
    <td><abbr title="Rotate L left">RL L</abbr></td>
    <td><abbr title="Rotate value pointed by HL left">RL (HL)</abbr></td>
    <td><abbr title="Rotate A left">RL A</abbr></td>
    <td><abbr title="Rotate B right">RR B</abbr></td>
    <td><abbr title="Rotate C right">RR C</abbr></td>
    <td><abbr title="Rotate D right">RR D</abbr></td>
    <td><abbr title="Rotate E right">RR E</abbr></td>
    <td><abbr title="Rotate H right">RR H</abbr></td>
    <td><abbr title="Rotate L right">RR L</abbr></td>
    <td><abbr title="Rotate value pointed by HL right">RR (HL)</abbr></td>
    <td><abbr title="Rotate A right">RR A</abbr></td>
   </tr>
   <tr>
    <td><strong>2x</strong></td>
    <td><abbr title="Shift B left preserving sign">SLA B</abbr></td>
    <td><abbr title="Shift C left preserving sign">SLA C</abbr></td>
    <td><abbr title="Shift D left preserving sign">SLA D</abbr></td>
    <td><abbr title="Shift E left preserving sign">SLA E</abbr></td>
    <td><abbr title="Shift H left preserving sign">SLA H</abbr></td>
    <td><abbr title="Shift L left preserving sign">SLA L</abbr></td>
    <td><abbr title="Shift value pointed by HL left preserving sign">SLA (HL)</abbr></td>
    <td><abbr title="Shift A left preserving sign">SLA A</abbr></td>
    <td><abbr title="Shift B right preserving sign">SRA B</abbr></td>
    <td><abbr title="Shift C right preserving sign">SRA C</abbr></td>
    <td><abbr title="Shift D right preserving sign">SRA D</abbr></td>
    <td><abbr title="Shift E right preserving sign">SRA E</abbr></td>
    <td><abbr title="Shift H right preserving sign">SRA H</abbr></td>
    <td><abbr title="Shift L right preserving sign">SRA L</abbr></td>
    <td><abbr title="Shift value pointed by HL right preserving sign">SRA (HL)</abbr></td>
    <td><abbr title="Shift A right preserving sign">SRA A</abbr></td>
   </tr>
   <tr>
    <td><strong>3x</strong></td>
    <td><abbr title="Swap nybbles in B">SWAP B</abbr></td>
    <td><abbr title="Swap nybbles in C">SWAP C</abbr></td>
    <td><abbr title="Swap nybbles in D">SWAP D</abbr></td>
    <td><abbr title="Swap nybbles in E">SWAP E</abbr></td>
    <td><abbr title="Swap nybbles in H">SWAP H</abbr></td>
    <td><abbr title="Swap nybbles in L">SWAP L</abbr></td>
    <td><abbr title="Swap nybbles in value pointed by HL">SWAP (HL)</abbr></td>
    <td><abbr title="Swap nybbles in A">SWAP A</abbr></td>
    <td><abbr title="Shift B right">SRL B</abbr></td>
    <td><abbr title="Shift C right">SRL C</abbr></td>
    <td><abbr title="Shift D right">SRL D</abbr></td>
    <td><abbr title="Shift E right">SRL E</abbr></td>
    <td><abbr title="Shift H right">SRL H</abbr></td>
    <td><abbr title="Shift L right">SRL L</abbr></td>
    <td><abbr title="Shift value pointed by HL right">SRL (HL)</abbr></td>
    <td><abbr title="Shift A right">SRL A</abbr></td>
   </tr>
   <tr>
    <td><strong>4x</strong></td>
    <td><abbr title="Test bit 0 of B">BIT 0,B</abbr></td>
    <td><abbr title="Test bit 0 of C">BIT 0,C</abbr></td>
    <td><abbr title="Test bit 0 of D">BIT 0,D</abbr></td>
    <td><abbr title="Test bit 0 of E">BIT 0,E</abbr></td>
    <td><abbr title="Test bit 0 of H">BIT 0,H</abbr></td>
    <td><abbr title="Test bit 0 of L">BIT 0,L</abbr></td>
    <td><abbr title="Test bit 0 of value pointed by HL">BIT 0,(HL)</abbr></td>
    <td><abbr title="Test bit 0 of A">BIT 0,A</abbr></td>
    <td><abbr title="Test bit 1 of B">BIT 1,B</abbr></td>
    <td><abbr title="Test bit 1 of C">BIT 1,C</abbr></td>
    <td><abbr title="Test bit 1 of D">BIT 1,D</abbr></td>
    <td><abbr title="Test bit 1 of E">BIT 1,E</abbr></td>
    <td><abbr title="Test bit 1 of H">BIT 1,H</abbr></td>
    <td><abbr title="Test bit 1 of L">BIT 1,L</abbr></td>
    <td><abbr title="Test bit 1 of value pointed by HL">BIT 1,(HL)</abbr></td>
    <td><abbr title="Test bit 1 of A">BIT 1,A</abbr></td>
   </tr>
   <tr>
    <td><strong>5x</strong></td>
    <td><abbr title="Test bit 2 of B">BIT 2,B</abbr></td>
    <td><abbr title="Test bit 2 of C">BIT 2,C</abbr></td>
    <td><abbr title="Test bit 2 of D">BIT 2,D</abbr></td>
    <td><abbr title="Test bit 2 of E">BIT 2,E</abbr></td>
    <td><abbr title="Test bit 2 of H">BIT 2,H</abbr></td>
    <td><abbr title="Test bit 2 of L">BIT 2,L</abbr></td>
    <td><abbr title="Test bit 2 of value pointed by HL">BIT 2,(HL)</abbr></td>
    <td><abbr title="Test bit 2 of A">BIT 2,A</abbr></td>
    <td><abbr title="Test bit 3 of B">BIT 3,B</abbr></td>
    <td><abbr title="Test bit 3 of C">BIT 3,C</abbr></td>
    <td><abbr title="Test bit 3 of D">BIT 3,D</abbr></td>
    <td><abbr title="Test bit 3 of E">BIT 3,E</abbr></td>
    <td><abbr title="Test bit 3 of H">BIT 3,H</abbr></td>
    <td><abbr title="Test bit 3 of L">BIT 3,L</abbr></td>
    <td><abbr title="Test bit 3 of value pointed by HL">BIT 3,(HL)</abbr></td>
    <td><abbr title="Test bit 3 of A">BIT 3,A</abbr></td>
   </tr>
   <tr>
    <td><strong>6x</strong></td>
    <td><abbr title="Test bit 4 of B">BIT 4,B</abbr></td>
    <td><abbr title="Test bit 4 of C">BIT 4,C</abbr></td>
    <td><abbr title="Test bit 4 of D">BIT 4,D</abbr></td>
    <td><abbr title="Test bit 4 of E">BIT 4,E</abbr></td>
    <td><abbr title="Test bit 4 of H">BIT 4,H</abbr></td>
    <td><abbr title="Test bit 4 of L">BIT 4,L</abbr></td>
    <td><abbr title="Test bit 4 of value pointed by HL">BIT 4,(HL)</abbr></td>
    <td><abbr title="Test bit 4 of A">BIT 4,A</abbr></td>
    <td><abbr title="Test bit 5 of B">BIT 5,B</abbr></td>
    <td><abbr title="Test bit 5 of C">BIT 5,C</abbr></td>
    <td><abbr title="Test bit 5 of D">BIT 5,D</abbr></td>
    <td><abbr title="Test bit 5 of E">BIT 5,E</abbr></td>
    <td><abbr title="Test bit 5 of H">BIT 5,H</abbr></td>
    <td><abbr title="Test bit 5 of L">BIT 5,L</abbr></td>
    <td><abbr title="Test bit 5 of value pointed by HL">BIT 5,(HL)</abbr></td>
    <td><abbr title="Test bit 5 of A">BIT 5,A</abbr></td>
   </tr>
   <tr>
    <td><strong>7x</strong></td>
    <td><abbr title="Test bit 6 of B">BIT 6,B</abbr></td>
    <td><abbr title="Test bit 6 of C">BIT 6,C</abbr></td>
    <td><abbr title="Test bit 6 of D">BIT 6,D</abbr></td>
    <td><abbr title="Test bit 6 of E">BIT 6,E</abbr></td>
    <td><abbr title="Test bit 6 of H">BIT 6,H</abbr></td>
    <td><abbr title="Test bit 6 of L">BIT 6,L</abbr></td>
    <td><abbr title="Test bit 6 of value pointed by HL">BIT 6,(HL)</abbr></td>
    <td><abbr title="Test bit 6 of A">BIT 6,A</abbr></td>
    <td><abbr title="Test bit 7 of B">BIT 7,B</abbr></td>
    <td><abbr title="Test bit 7 of C">BIT 7,C</abbr></td>
    <td><abbr title="Test bit 7 of D">BIT 7,D</abbr></td>
    <td><abbr title="Test bit 7 of E">BIT 7,E</abbr></td>
    <td><abbr title="Test bit 7 of H">BIT 7,H</abbr></td>
    <td><abbr title="Test bit 7 of L">BIT 7,L</abbr></td>
    <td><abbr title="Test bit 7 of value pointed by HL">BIT 7,(HL)</abbr></td>
    <td><abbr title="Test bit 7 of A">BIT 7,A</abbr></td>
   </tr>
   <tr>
    <td><strong>8x</strong></td>
    <td><abbr title="Clear (reset) bit 0 of B">RES 0,B</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of C">RES 0,C</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of D">RES 0,D</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of E">RES 0,E</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of H">RES 0,H</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of L">RES 0,L</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of value pointed by HL">RES 0,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 0 of A">RES 0,A</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of B">RES 1,B</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of C">RES 1,C</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of D">RES 1,D</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of E">RES 1,E</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of H">RES 1,H</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of L">RES 1,L</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of value pointed by HL">RES 1,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 1 of A">RES 1,A</abbr></td>
   </tr>
   <tr>
    <td><strong>9x</strong></td>
    <td><abbr title="Clear (reset) bit 2 of B">RES 2,B</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of C">RES 2,C</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of D">RES 2,D</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of E">RES 2,E</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of H">RES 2,H</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of L">RES 2,L</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of value pointed by HL">RES 2,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 2 of A">RES 2,A</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of B">RES 3,B</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of C">RES 3,C</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of D">RES 3,D</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of E">RES 3,E</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of H">RES 3,H</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of L">RES 3,L</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of value pointed by HL">RES 3,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 3 of A">RES 3,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Ax</strong></td>
    <td><abbr title="Clear (reset) bit 4 of B">RES 4,B</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of C">RES 4,C</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of D">RES 4,D</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of E">RES 4,E</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of H">RES 4,H</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of L">RES 4,L</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of value pointed by HL">RES 4,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 4 of A">RES 4,A</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of B">RES 5,B</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of C">RES 5,C</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of D">RES 5,D</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of E">RES 5,E</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of H">RES 5,H</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of L">RES 5,L</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of value pointed by HL">RES 5,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 5 of A">RES 5,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Bx</strong></td>
    <td><abbr title="Clear (reset) bit 6 of B">RES 6,B</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of C">RES 6,C</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of D">RES 6,D</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of E">RES 6,E</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of H">RES 6,H</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of L">RES 6,L</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of value pointed by HL">RES 6,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 6 of A">RES 6,A</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of B">RES 7,B</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of C">RES 7,C</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of D">RES 7,D</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of E">RES 7,E</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of H">RES 7,H</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of L">RES 7,L</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of value pointed by HL">RES 7,(HL)</abbr></td>
    <td><abbr title="Clear (reset) bit 7 of A">RES 7,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Cx</strong></td>
    <td><abbr title="Set bit 0 of B">SET 0,B</abbr></td>
    <td><abbr title="Set bit 0 of C">SET 0,C</abbr></td>
    <td><abbr title="Set bit 0 of D">SET 0,D</abbr></td>
    <td><abbr title="Set bit 0 of E">SET 0,E</abbr></td>
    <td><abbr title="Set bit 0 of H">SET 0,H</abbr></td>
    <td><abbr title="Set bit 0 of L">SET 0,L</abbr></td>
    <td><abbr title="Set bit 0 of value pointed by HL">SET 0,(HL)</abbr></td>
    <td><abbr title="Set bit 0 of A">SET 0,A</abbr></td>
    <td><abbr title="Set bit 1 of B">SET 1,B</abbr></td>
    <td><abbr title="Set bit 1 of C">SET 1,C</abbr></td>
    <td><abbr title="Set bit 1 of D">SET 1,D</abbr></td>
    <td><abbr title="Set bit 1 of E">SET 1,E</abbr></td>
    <td><abbr title="Set bit 1 of H">SET 1,H</abbr></td>
    <td><abbr title="Set bit 1 of L">SET 1,L</abbr></td>
    <td><abbr title="Set bit 1 of value pointed by HL">SET 1,(HL)</abbr></td>
    <td><abbr title="Set bit 1 of A">SET 1,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Dx</strong></td>
    <td><abbr title="Set bit 2 of B">SET 2,B</abbr></td>
    <td><abbr title="Set bit 2 of C">SET 2,C</abbr></td>
    <td><abbr title="Set bit 2 of D">SET 2,D</abbr></td>
    <td><abbr title="Set bit 2 of E">SET 2,E</abbr></td>
    <td><abbr title="Set bit 2 of H">SET 2,H</abbr></td>
    <td><abbr title="Set bit 2 of L">SET 2,L</abbr></td>
    <td><abbr title="Set bit 2 of value pointed by HL">SET 2,(HL)</abbr></td>
    <td><abbr title="Set bit 2 of A">SET 2,A</abbr></td>
    <td><abbr title="Set bit 3 of B">SET 3,B</abbr></td>
    <td><abbr title="Set bit 3 of C">SET 3,C</abbr></td>
    <td><abbr title="Set bit 3 of D">SET 3,D</abbr></td>
    <td><abbr title="Set bit 3 of E">SET 3,E</abbr></td>
    <td><abbr title="Set bit 3 of H">SET 3,H</abbr></td>
    <td><abbr title="Set bit 3 of L">SET 3,L</abbr></td>
    <td><abbr title="Set bit 3 of value pointed by HL">SET 3,(HL)</abbr></td>
    <td><abbr title="Set bit 3 of A">SET 3,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Ex</strong></td>
    <td><abbr title="Set bit 4 of B">SET 4,B</abbr></td>
    <td><abbr title="Set bit 4 of C">SET 4,C</abbr></td>
    <td><abbr title="Set bit 4 of D">SET 4,D</abbr></td>
    <td><abbr title="Set bit 4 of E">SET 4,E</abbr></td>
    <td><abbr title="Set bit 4 of H">SET 4,H</abbr></td>
    <td><abbr title="Set bit 4 of L">SET 4,L</abbr></td>
    <td><abbr title="Set bit 4 of value pointed by HL">SET 4,(HL)</abbr></td>
    <td><abbr title="Set bit 4 of A">SET 4,A</abbr></td>
    <td><abbr title="Set bit 5 of B">SET 5,B</abbr></td>
    <td><abbr title="Set bit 5 of C">SET 5,C</abbr></td>
    <td><abbr title="Set bit 5 of D">SET 5,D</abbr></td>
    <td><abbr title="Set bit 5 of E">SET 5,E</abbr></td>
    <td><abbr title="Set bit 5 of H">SET 5,H</abbr></td>
    <td><abbr title="Set bit 5 of L">SET 5,L</abbr></td>
    <td><abbr title="Set bit 5 of value pointed by HL">SET 5,(HL)</abbr></td>
    <td><abbr title="Set bit 5 of A">SET 5,A</abbr></td>
   </tr>
   <tr>
    <td><strong>Fx</strong></td>
    <td><abbr title="Set bit 6 of B">SET 6,B</abbr></td>
    <td><abbr title="Set bit 6 of C">SET 6,C</abbr></td>
    <td><abbr title="Set bit 6 of D">SET 6,D</abbr></td>
    <td><abbr title="Set bit 6 of E">SET 6,E</abbr></td>
    <td><abbr title="Set bit 6 of H">SET 6,H</abbr></td>
    <td><abbr title="Set bit 6 of L">SET 6,L</abbr></td>
    <td><abbr title="Set bit 6 of value pointed by HL">SET 6,(HL)</abbr></td>
    <td><abbr title="Set bit 6 of A">SET 6,A</abbr></td>
    <td><abbr title="Set bit 7 of B">SET 7,B</abbr></td>
    <td><abbr title="Set bit 7 of C">SET 7,C</abbr></td>
    <td><abbr title="Set bit 7 of D">SET 7,D</abbr></td>
    <td><abbr title="Set bit 7 of E">SET 7,E</abbr></td>
    <td><abbr title="Set bit 7 of H">SET 7,H</abbr></td>
    <td><abbr title="Set bit 7 of L">SET 7,L</abbr></td>
    <td><abbr title="Set bit 7 of value pointed by HL">SET 7,(HL)</abbr></td>
    <td><abbr title="Set bit 7 of A">SET 7,A</abbr></td>
   </tr>
  </tbody>
 </table>
 <figcaption>Table 2: Two-byte instruction codes (CB-prefix table)</figcaption>
</figure>
 ]]></content>
</entry>
<entry>
 <title type="html">Implementing PayPal Website Payments Pro UK</title>
 <link href="https://imrannazar.com/articles/paypal-wpp-uk" rel="alternate" type="text/html" title="Implementing PayPal Website Payments Pro UK" />
 <id>https://imrannazar.com/articles/paypal-wpp-uk</id>
 <summary>PayPal is used across the world to authorise payments online, and a seamless credit card payment service is available through Website Payments Pro. Unfortunately, the documentation for implementing this can be confusing and contradictory, and getting your code working can take some time. In this article I&#039;ve brought together the documentation and my experience with it, to provide a coherent source of information on Website Payments Pro.</summary>
 <category term="Articles" />
 <published>Tue, 15 Sep 2009 17:52:31 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One of the most popular methods for a website to take payments for goods and services is through PayPal, the online payment service. In particular, it's possible to authenticate credit and debit cards directly through PayPal without the need for the customer to have a PayPal account; this service is referred to as Website Payments Pro.</p>
<p>In the UK, Website Payments Pro is implemented as a REST or SOAP API, to which a website can connect and request transactions. There are, however, some pitfalls to implementing these requests:</p>
<dl>
 <dt>Inadequate documentation:</dt>
 <dd>PayPal provide at least three conflicting versions of the documentation for the API, each covering a different revision of the API itself; none are marked as current relative to the others, and the API as used in production incorporates elements of each. As such, it can be difficult to produce a working API request.</dd>
 <dt>The sandbox:</dt>
 <dd>A "sandbox" environment is provided for testing of API requests before they are used to process live transactions. The principle is well thought-out, but the sandbox has issues: it provides a different revision of the service to the live process, and the server hosting the sandbox is often unresponsive. This makes it, at best, time-consuming to use the sandbox.</dd>
 <dt>Two transaction methods:</dt>
 <dd>In order to provide the ability to process credit or debit cards directly (referred to as Direct Payment), PayPal stipulate that a three-step process called Express Checkout also be available for PayPal users without a card to hand. The matter of maintaining state within an Express Checkout transaction can be troublesome, and the process must be kept distinct and separate from Direct Payments.</dd>
</dl>
<p>I fell into all of the above traps when implementing WPP, so I produced the following article for reference purposes, and to serve as a coherent source of documentation for implementatin of Website Payments Pro. Please note that throughout, the API revision used is 56.0, and REST calls will be used.</p>
<h2>The Basics: API calls</h2>
<p>The PayPal REST API is called by POSTing a request to a secure (HTTPS) URI, with credentials generated by the holder of a "business" PayPal account. The credentials consist of an API "user" based on the account holder's email address, a credential password, and an encoded "signature" used as an additional checksum by the API. An example set of credentials would look as follows:</p>
<samp>
 <h3>API credentials (example):</h3>
 <pre>USER:       tf_api1.imrannazar.com
PWD:        QF63NP99NPER3V7A
SIGNATURE:  AZM6n0EcNmR0AQYsCf0s1VrwkV10AlKArJ7a8X4YHG-R2oFkOwGqVrJZ
VERSION:    56.0</pre>
</samp>
<p>These variables are passed, along with the transaction request parameters, in a standard POST-formatted query to the previously mentioned HTTPS URI. The API will return a POST-formatted string with the result of the transaction request, which can be split manually or with a scripting language's built-in functions. The examples in this article are written in PHP, which provides functions to build and to break up POST-format strings. The following code will produce and send a request to the PayPal API, parsing and returning the result.</p>
<samp>
 <h3>PHP cURL code to call the PayPal API</h3>
 <pre><kbd>class</kbd> PaymentPaypal
{
    <kbd>const</kbd> <var>API_URI</var> = <var>'https://api-3t.paypal.com/nvp'</var>;

    <s>// PayPal API credential configuration</s>
    <kbd>private</kbd> $config;

    <s>// Data for this transaction (cart ID/contents/amount)</s>
    <kbd>private</kbd> $data;

    <kbd>function</kbd> send($params)
    {
	$params[<var>'USER'</var>]      = $<kbd>this</kbd>-&gt;config[<var>'USER'</var>];
	$params[<var>'PWD'</var>]       = $<kbd>this</kbd>-&gt;config[<var>'PWD'</var>];
	$params[<var>'SIGNATURE'</var>] = $<kbd>this</kbd>-&gt;config[<var>'SIGNATURE'</var>];
	$params[<var>'VERSION'</var>]   = <var>'56.0'</var>;

	<s>// Fire up a POST request to PayPal</s>
	$c = <kbd>curl_init</kbd>();
	<kbd>curl_setopt_array</kbd>($c, <kbd>array</kbd>(
	    <var>CURLOPT_URL</var>            =&gt; <kbd>self</kbd>::<var>API_URI</var>,
	    <var>CURLOPT_FAILONERROR</var>    =&gt; <var>true</var>,
	    <var>CURLOPT_RETURNTRANSFER</var> =&gt; <var>true</var>,
	    <var>CURLOPT_FOLLOWLOCATION</var> =&gt; <var>true</var>,
	    <var>CURLOPT_POST</var>           =&gt; <var>true</var>,
	    <var>CURLOPT_POSTFIELDS</var>     =&gt; <kbd>http_build_query</kbd>($params)
	));

	$result = <var>curl_exec</var>($c);

	<kbd>if</kbd>(!$result)
	{
	    <s>// Request failed at HTTP time; return the cURL error</s>
	    <kbd>return array</kbd>(<var>'ERROR'</var> =&gt; <kbd>curl_error</kbd>($c));
	}
	<kbd>else</kbd>
	{
	    <s>// Request returned; break out the response into an array</s>
	    <kbd>curl_close</kbd>($c):
	    $r = <kbd>array</kbd>();
	    <kbd>parse_str</kbd>($result, $r);
	    <kbd>return</kbd> $r;
	}
    }
}</pre>
</samp>
<p>The <code>config</code> member variable for this class can be filled at construction time, and its handling is not shown here.</p>
<h2>Error handling</h2>
<p>As shown above, a rudimentary catch can be made if PayPal refuses to respond properly, since cURL will produce an error in such a circumstance. However, if the request succeeds but PayPal returns an error, these errors must also be accounted for. PayPal allows for this by sending error messages back with the response as appropriate.</p>
<p>If any error messages are provided in the response, they will be provided in three formats:</p>
<ul>
 <li><strong><code>L_ERRORCODEx</code></strong>: An error code for referencing against <a href="https://www.paypal.com/en_US/ebook/PP_APIReference/Appx-ErrorCodes_and_Messages.html">PayPal's list of error codes and messages</a>;</li>
 <li><strong><code>L_SHORTMESSAGEx</code></strong>: A short technical description of the error;</li>
 <li><strong><code>L_LONGMESSAGEx</code></strong>: A long description which can be printed direct to the user.</li>
</ul>
<p>PayPal recommend that if a message is to be printed to the user when you trap an error, it should be the long message, since the short message may be difficult to understand. An example of such a situation is error code <code>10537</code>, "Risk Control Country Filter Failure". The long message for this is currently documented as: "The transaction was refused because the country was prohibited as a result of your Country Monitor Risk Control Settings", which is eminently more understandable than the short message or the error code itself.</p>
<p>Since a PayPal transaction may result in more than one error, each set of error code and messages is suffixed with a number, denoted with "x" above. The numbers start at 0, which means that any failure in an API call is usually documented in the <code>L_LONGMESSAGE0</code> part of the response. If <code>L_LONGMESSAGE0</code> doesn't sufficiently explain the cause of the error, your code can check for any other errors that may have arisen.</p>
<h2>Before the request: User input</h2>
<p>As previously mentioned, PayPal allows users of Website Payments Pro to use either Express Checkout (EC) or Direct Payments (DP) to authenticate a transaction. In order to provide the choice, and to take credit card details if DP is to be used, a form must be presented to the user stating how much is to be paid, and showing the two methods.</p>
<p>PayPal stipulate the following requirements for this input form:</p>
<ul>
 <li>The form must state the cost to the user for this transaction (the amount to be paid).</li>
 <li>An "Express Checkout" button must be provided, which will start the EC process.</li>
 <li>A form to take credit card details must be provided if DP is to be used by the website, which must provide to PayPal the billing name and address as well as card details.</li>
</ul>
<p>The form may be rendered however you wish, and the billing name and address can be taken beforehand from a previously registered account or provided directly with the card details in the DP form. An example would look as follows.</p>
<figure>
 <img src="https://imrannazar.com/content/img/paypal-wpp-form.gif" alt="Payment input form with both methods">
 <figcaption>Figure 1: Payment input form</figcaption>
</figure>
<h2>Express Checkout</h2>
<p>The Express Checkout process runs in three stages, allowing a user to log in to PayPal and use their account balance to pay for the transaction. Once they've logged in, they can confirm their information such as a shipping address if the website requires it, and then the transaction is sent through the API to be charged against the PayPal account.</p>
<figure class="invertable">
 <img src="https://imrannazar.com/content/img/paypal-wpp-ec.gif" alt="Express Checkout process">
 <figcaption>Figure 2: Express Checkout process</figcaption>
</figure>
<p>The first step, referred to as <code>SetExpressCheckout</code> in the documentation, is to generate a transaction "token" that will allow both your site and PayPal to track through the three steps: this is done by calling PayPal through the API and requesting an EC token. Once the token has been generated, the user is forwarded to PayPal so that they can log in, and PayPal will then return the user to your site.</p>
<figure>
 <table>
  <thead><tr><th>Req/Ret</th><th>Name</th><th>Value</th></tr></thead>
  <tbody>
   <tr><td><em>Request</em></td><td>TRXTYPE</td><td><strong>S</strong></td></tr>
   <tr><td><em>Request</em></td><td>ACTION</td><td><strong>S</strong></td></tr>
   <tr><td><em>Request</em></td><td>AMT</td><td>Amount of the transaction</td></tr>
   <tr><td><em>Request</em></td><td>CURRENCYCODE</td><td>Currency of the transaction (<strong>GBP</strong>)</td></tr>
   <tr><td><em>Request</em></td><td>RETURNURL</td><td>URL for PayPal to direct to for stage 2</td></tr>
   <tr><td><em>Request</em></td><td>CANCELURL</td><td>URL for PayPal to direct to if cancelled</td></tr>
   <tr><td><strong>Return</strong></td><td>ACK</td><td><strong>Success</strong> or <strong>Failure</strong></td></tr>
   <tr><td><strong>Return</strong></td><td>TOKEN</td><td>Generated token</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: API parameters for Express Checkout stage 1</figcaption>
</figure>
<p>If the API return comes back with an <code>ACK</code> value of "Failure", the return will not contain a <code>TOKEN</code>; this can be used to check whether the request for a token succeeded.</p>
<p>The URL parameters to the stage-1 request allow a website to know whether a user has proceeded to step 2, or has cancelled the transaction at the PayPal side. By passing transaction information like the ID through these URLs, the website can be informed and take the appropriate action, such as marking a transaction as "Cancelled" if the <code>CANCELURL</code> is triggered. The URLs shown for this purpose below link into a ficticious routing framework, but they can be modified to match your configuration.</p>
<samp>
 <h3>Request code for Express Checkout stage 1</h3>
 <pre><kbd>class</kbd> PaymentPaypal
{
    <kbd>function</kbd> express_stg1()
    {
        $params = <kbd>array</kbd>(
	    <var>'TRXTYPE'</var>      =&gt; <var>'S'</var>,
	    <var>'ACTION'</var>       =&gt; <var>'S'</var>,
	    <var>'AMT'</var>          =&gt; $<kbd>this</kbd>-&gt;data[<var>'transaction_amount'</var>],
	    <var>'CURRENCYCODE'</var> =&gt; <var>'GBP'</var>,
	    <var>'RETURNURL'</var>    =&gt;' ($<kbd>this</kbd>-&gt;config[<var>'SITEBASE'</var>].<var>'/checkout/ec2/'</var>.$<kbd>this</kbd>-&gt;data[<var>'transaction_id'</var>]),
	    <var>'CANCELURL'</var>    =&gt; ($<kbd>this</kbd>-&gt;config[<var>'SITEBASE'</var>].<var>'/checkout/cancel/'</var>.$<kbd>this</kbd>-&gt;data[<var>'transaction_id'</var>])
	);

	$response = $<kbd>this</kbd>-&gt;send($params);

	<kbd>if</kbd>($response[<var>'ACK'</var>] == <var>'Failure'</var> || !<kbd>isset</kbd>($response[<var>'TOKEN'</var>]))
	{
	    <s>// Request failed; return error</s>
	    <kbd>return array</kbd>(
	    	<var>'status'</var> =&gt; <var>'FAIL'</var>,
		<var>'msg'</var> =&gt; $response[<var>'L_LONGMESSAGE0'</var>]
	    );
	}
	<kbd>else</kbd>
	{
	    <s>// Request successful; forward user to PayPal and end script</s>
	    <kbd>header</kbd>(<var>'Location: https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&amp;token='</var>.$response[<var>'TOKEN'</var>]);
	    <kbd>die</kbd>(<var>'FORWARD'</var>);
	}
    }
}</pre>
</samp>
<p>Once the user has logged into PayPal and returned to your site, PayPal allow for the retrieval of the token and further redirection for entering a shipping address and related details, through the step named <code>GetExpressCheckout</code>. This can be advantageous if your site doesn't have the ability to tie a billing and shipping address against a given user's profile, but PayPal state that this second step can be skipped if these details are already on file against a profile on your site. I've found it simpler to deal with these parts of the profile directly, than forward through PayPal again, so stage 2 of Express Checkout is simply a button to take the user to stage 3. This can be implemented, of course, as a direct link to stage 3 using the <code>RETURNURL</code> parameter to the stage-1 call.</p>
<p>Either way that this is implemented, the URL returned to will be provided with two parameters on the GET line: the original EC token generated in stage 1, and a <code>PayerID</code> which corresponds to the login given by the user to PayPal. The third stage of Express Checkout, <code>DoExpressCheckout</code>, does the actual work of firing a transaction through the API using the authenticated token provided by the PayPal user, and uses both of these as parameters to the API call.</p>
<figure>
 <table>
  <thead><tr><th>Req/Ret</th><th>Name</th><th>Value</th></tr></thead>
  <tbody>
   <tr><td><em>Request</em></td><td>TRXTYPE</td><td><strong>S</strong></td></tr>
   <tr><td><em>Request</em></td><td>ACTION</td><td><strong>D</strong></td></tr>
   <tr><td><em>Request</em></td><td>AMT</td><td>Amount of the transaction</td></tr>
   <tr><td><em>Request</em></td><td>CURRENCYCODE</td><td>Currency of the transaction (<strong>GBP</strong>)</td></tr>
   <tr><td><em>Request</em></td><td>TOKEN</td><td>EC token generated in stage 1</td></tr>
   <tr><td><em>Request</em></td><td>PAYERID</td><td>PayerID returned to stage 2</td></tr>
   <tr><td><em>Request</em></td><td>PAYMENTACTION</td><td><strong>Sale</strong> or <strong>Authorization</strong></td></tr>
   <tr><td><strong>Return</strong></td><td>RESULT</td><td>0 if successful, positive for comms error, negative for declined</td></tr>
   <tr><td><strong>Return</strong></td><td>RESPMSG</td><td>Short description of EC result</td></tr>
  </tbody>
 </table>
 <figcaption>Table 2: API parameters for Express Checkout stage 3</figcaption>
</figure>
<p>The only new parameter here is <code>PAYMENTACTION</code>; this allows for a PayPal account to be checked for authorisation without proceeding with a full sale, and can be useful for testing purposes as well as advanced purposes such as recurring billing and invoicing. Such features of the Express Checkout are beyond the scope of this article, but PayPal provide a <a href="https://cms.paypal.com/cms_content/US/en_US/files/developer/PP_WebsitePaymentsPro_IntegrationGuide_UK.pdf">PDF describing EC integration</a> which goes into some detail about these. (Note, however, that this documentation is outdated in its description of the basic sending of API requests; the method described in this article is more current.) For the moment, it's sufficient to set this to <code>Sale</code> and request a full transaction every time.</p>
<p>In addition to checking the standard error codes for a PayPal response, it's prudent to check the <code>RESULT</code> of the stage-3 call, to ensure that it comes back as a successful transaction (zero). If another value is set, the <code>RESPMSG</code> will describe what happened to the transaction, such as "Declined".</p>
<samp>
 <h3>Request code for Express Checkout stage 3</h3>
 <pre><kbd>class</kbd> PaymentPaypal
{
    <kbd>function</kbd> express_stg3($token, $payerid)
    {
        $params = <kbd>array</kbd>(
	    <var>'TRXTYPE'</var>       =&gt; <var>'S'</var>,
	    <var>'ACTION'</var>        =&gt; <var>'D'</var>,
	    <var>'AMT'</var>           =&gt; $<kbd>this</kbd>-&gt;data[<var>'transaction_amount'</var>],
	    <var>'CURRENCYCODE'</var>  =&gt; <var>'GBP'</var>,
	    <var>'TOKEN'</var>         =&gt; $token,
	    <var>'PAYERID'</var>       =&gt; $payerid,
	    <var>'PAYMENTACTION'</var> =&gt; <var>'Sale'</var>
	);

	$response = $<kbd>this</kbd>-&gt;send($params);

	<kbd>if</kbd>(<kbd>isset</kbd>($response[<var>'L_ERRORCODE0'</var>]) || $response[<var>'RESULT'</var>] != <var>0</var> || !<kbd>isset</kbd>($response[<var>'TOKEN'</var>]))
	{
	    <kbd>return array</kbd>(
	        <var>'status'</var> =&gt; <var>'FAIL'</var>,
		<var>'msg'</var> =&gt; $response[<var>'RESPMSG'</var>]
	    );
	}
	<kbd>else</kbd>
	{
	    <kbd>return array</kbd>(
	        <var>'status'</var> =&gt; <var>'PASS'</var>,
		<var>'msg'</var> =&gt; <var>'Transaction complete'</var>
	    );
	}
    }
}</pre>
</samp>
<h2>Direct Payment</h2>
<p>The alternative to Express Checkout is Direct Payment, the immediate charging of a credit or debit card without the user needing to sign up to PayPal. DP takes a set of card details, along with a billing name and address, and sends them through PayPal; the response will either be a successful charge against the card, or a failure with one of a number of reasons: mismatched billing name, invalid card number, and so forth. Because a good deal of information is asked for by DP, all the request fields below are required unless marked otherwise.</p>
<figure>
 <table>
  <thead><tr><th>Req/Ret</th><th>Name</th><th>Value</th></tr></thead>
  <tbody>
   <tr><td cols="3" style="text-align:center"><em>Transaction details</em></td></tr>
   <tr><td><em>Request</em></td><td>TRXTYPE</td><td><strong>S</strong></td></tr>
   <tr><td><em>Request</em></td><td>TENDER</td><td><strong>C</strong></td></tr>
   <tr><td><em>Request</em></td><td>AMT</td><td>Amount of the transaction</td></tr>
   <tr><td><em>Request</em></td><td>CURRENCYCODE</td><td>Currency of the transaction (<strong>GBP</strong>)</td></tr>
   <tr><td><em>Request</em></td><td>METHOD</td><td><strong>DoDirectPayment</strong></td></tr>
   <tr><td><em>Request</em></td><td>PAYMENTACTION</td><td><strong>Sale</strong></td></tr>
   <tr><td><em>Request</em></td><td>IPADDRESS</td><td>User's remote IP</td></tr>
   <tr><td cols="3" style="text-align:center"><em>Card details</em></td></tr>
   <tr><td><em>Request</em></td><td>CREDITCARDTYPE</td><td>Type of card<br>(<strong>Visa</strong>, <strong>MasterCard</strong>, <strong>Amex</strong>, <strong>Maestro</strong>, <strong>Solo</strong>)</td></tr>
   <tr><td><em>Request</em></td><td>ACCT</td><td>Card number (12-20 digits)</td></tr>
   <tr><td><em>Request</em></td><td>EXPDATE</td><td>Expiry date (MMYYYY, month is 01-12)</td></tr>
   <tr><td><em>Request</em></td><td>STARTDATE</td><td>Start date (MMYYYY, month is 01-12)<br><em>Required for Maestro and Solo cards only</em></td></tr>
   <tr><td><em>Request</em></td><td>CVV2</td><td>Card security code (3-6 digits)</td></tr>
   <tr><td><em>Request</em></td><td>FIRSTNAME</td><td>Cardholder's forename</td></tr>
   <tr><td><em>Request</em></td><td>LASTNAME</td><td>Cardholder's surname</td></tr>
   <tr><td><em>Request</em></td><td>STREET</td><td>Billing house number/name and street</td></tr>
   <tr><td><em>Request</em></td><td>STREET2</td><td>[Optional] Second billing address line</td></tr>
   <tr><td><em>Request</em></td><td>CITY</td><td>Billing address town/city</td></tr>
   <tr><td><em>Request</em></td><td>ZIP</td><td>Billing address postcode</td></tr>
   <tr><td><em>Request</em></td><td>COUNTRYCODE</td><td>Card issuing country (<strong>GB</strong>)</td></tr>
   <tr><td cols="3" style="text-align:center"><strong>Return</strong></td></tr>
   <tr><td><strong>Return</strong></td><td>ACK</td><td><strong>Success</strong> or <strong>Failure</strong></td></tr>
   <tr><td><strong>Return</strong></td><td>TRANSACTIONID</td><td>Alphanumeric ID given by PayPal</td></tr>
   <tr><td><strong>Return</strong></td><td>TIMESTAMP</td><td>ISO-formatted time and date of transaction</td></tr>
   <tr><td><strong>Return</strong></td><td>AMT</td><td>Amount of the transaction</td></tr>
   <tr><td><strong>Return</strong></td><td>CURRENCYCODE</td><td>Currency of the transaction (<strong>GBP</strong>)</td></tr>
  </tbody>
 </table>
 <figcaption>Table 3: API parameters for Direct Payment</figcaption>
</figure>
<p>PayPal will request address and CVV matching against the card when you send it through for processing; the results of these matches will be provided in the response along with the other parameters above, as the <code>AVSADDR</code>, <code>AVSZIP</code> and <code>CVV2MATCH</code> response values. Each of these will have one of the following characters as its value:</p>
<ul>
 <li><strong>Y</strong>: Value was matched against that held at the bank;</li>
 <li><strong>N</strong>: Value was checked and found to be incorrect;</li>
 <li><strong>X</strong>: Value was not checked.</li>
</ul>
<p>PayPal won't decline a transaction if these fail, but you can record these values against the transaction in case anything comes of them. The important flag, as with Express Checkout, is <code>ACK</code>; this will indicate whether the charge succeeded.</p>
<samp>
 <h3>Request code for Direct Payment</h3>
 <pre>class PaymentPayPal
{
    function direct($cc)
    {
        $params = <kbd>array</kbd>(
	    <var>'TRXTYPE'</var>        =&gt; <var>'S'</var>,
	    <var>'TENDER'</var>         =&gt; <var>'C'</var>,
	    <var>'AMT'</var>            =&gt; $<kbd>this</kbd>-&gt;data[<var>'transaction_amount'</var>],
	    <var>'CURRENCYCODE'</var>   =&gt; <var>'GBP'</var>,
	    <var>'METHOD'</var>         =&gt; <var>'DoDirectPayment'</var>,
	    <var>'PAYMENTACTION'</var>  =&gt; <var>'Sale'</var>,
	    <var>'IPADDRESS'</var>      =&gt; $_SERVER[<var>'REMOTE_ADDR'</var>],

	    <var>'CREDITCARDTYPE'</var> =&gt; $cc[<var>'type'</var>],
	    <var>'ACCT'</var>           =&gt; $cc[<var>'number'</var>],
	    <var>'EXPDATE'</var>        =&gt; <kbd>sprintf</kbd>(<var>'%02d%04d'</var>, $cc[<var>'expmonth'</var>], $cc[<var>'expyear'</var>],
	    <var>'CVV2'</var>           =&gt; $cc[<var>'cvv'</var>]
	    <var>'FIRSTNAME'</var>      =&gt; $<kbd>this</kbd>-&gt;data[<var>'user_fname'</var>],
	    <var>'LASTNAME'</var>       =&gt; $<kbd>this</kbd>-&gt;data[<var>'user_sname'</var>],
	    <var>'STREET'</var>         =&gt; $<kbd>this</kbd>-&gt;data[<var>'user_adstreet'</var>],
	    <var>'CITY'</var>           =&gt; $<kbd>this</kbd>-&gt;data[<var>'user_adtown'</var>],
	    <var>'ZIP'</var>            =&gt; $<kbd>this</kbd>-&gt;data[<var>'user_adpostcode'</var>],
	    <var>'COUNTRYCODE'</var>    =&gt; <var>'GB'</var>,
	);

	<s>// Fill in the start date if required</s>
	<kbd>if</kbd>($cc[<var>'type'</var>] == <var>'Maestro'</var> || $cc[<var>'type'</var>] == <var>'Solo'</var>)
	{
	    $params[<var>'STARTDATE'</var>] = <kbd>sprintf</kbd>(<var>'%02d%04d'</var>, $cc[<var>'startmonth'</var>], $cc[<var>'startyear'</var>]);
	}

	$response = $<kbd>this</kbd>-&gt;send($params);

	<kbd>if</kbd>(<kbd>isset</kbd>($response[<var>'L_ERRORCODE0'</var>]) || $response[<var>'ACK'</var>] == <var>'Failure'</var>)
	{
	    <kbd>return array</kbd>(
	        <var>'status'</var> =&gt; <var>'FAIL'</var>,
		<var>'msg'</var> =&gt; $response[<var>'L_LONGMESSAGE0'</var>]
	    );
	}
	else
	{
	    <kbd>return array</kbd>(
	        <var>'status'</var> =&gt; <var>'PASS'</var>,
		<var>'msg'</var> =&gt; <var>'Transaction complete'</var>
	    );
	}
    }
}</pre>
</samp>
<h2>Troubleshooting</h2>
<p>A few issues may come up while using the above routines; a couple of the most common ones I came across are documented below.</p>
<dl>
 <dt>Direct Payment transactions fail on small amounts of money:</dt>
 <dd>PayPal will only accept a credit or debit card for charging if the transaction is more than &pound;1.00; it's for this reason that the cost of the test transaction in Figure 1 is &pound;1.20, to get over this hurdle and allow PayPal to process the transaction.</dd>
 <dt>PayPal returns an "invalid merchant configuration" on Direct Payment:</dt>
 <dd>This most often comes up if the PayPal account holder has upgraded their account to Website Payments Pro, and then not paid the monthly &pound;20.00 fee; if this fee isn't paid, the Pro functionality and API access will be suspended, and the routines above won't have any valid credentials to connect with.</dd>
</dl>
<h2>In Closing</h2>
<p>That's pretty much all you need to know in order to send a transaction through PayPal Website Payments Pro. I haven't covered the more advanced aspects, such as recurring billing and refunds, but these are little more than different <code>TRXTYPE</code>'s and are adequately documented as such in PayPal's own documentation. Just be aware that the authentication methods have changed between various revisions of the API: if the documentation asks that you send a <code>VENDOR</code> value, you can safely ignore it.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Sep 2009</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Prime Point</title>
 <link href="https://imrannazar.com/scifi/prime-point" rel="alternate" type="text/html" title="Sci-fi Shorts: Prime Point" />
 <id>https://imrannazar.com/scifi/prime-point</id>
 <summary>A spacecraft is sent to the Earth-Sun L5 Lagrange point, where it undergoes testing. Vignette, sci-fi.</summary>
 <category term="Original Writings" />
 <published>Wed, 19 Aug 2009 08:39:22 +0000</published>
 <content type="text/html"><![CDATA[
   <p>It had been a long time coming, but they were almost ready.
</p><p>
The launch had happened a few months before; a Paludis III rocket had blasted
away from Guinea base, carrying a comms satellite and the HT probe. The probe
had unfurled right on schedule, and started on its push to the Lagrange point
that would be its destination. It was now reporting that it was approaching
L5, and that it was ready to spool up the experiment.

</p><p>
James Kent was quite excited. Even though it was 4am local time, he hadn't
been able to sleep knowing that HT was getting close to starting its job; he'd
driven in to the lab to watch the data as it came in. As he arrived at the
lab, it was obvious that no-one else involved on the project had been able to
get any rest, either.

</p><p>
"Morning", called a voice over his shoulder as James sat down. It was Mike
Rampton, the flight director; Mike would be overseeing operations in the
command centre, while James was in charge of crunching the numbers to make
sure the project ran smoothly.

</p><p>
"It's not morning yet, Mike. Status?" asked James.

</p><p>
"Looking good. HT's braking in towards L5 right now; obviously, our
telemetry's about a minute delayed, so I'd say it's holding in place right
now. We've secured the lunar scopes you wanted, so we should be able to see
things as they happen."

</p><p>
James had asked for a day's worth of time on the new lunar telescopes sent up
by Europe, mostly because it was difficult to see the Terran L5 point from
Earth itself. It had set the project back a fair bit of money, but the
telescopes had been contracted out to them for today, and both James and Mike
intended to make good use of them.

</p><p>
"Good thing about the 'scopes is, we can see HT clear as day. With no
atmosphere to cover up the view, our results will show up pretty well", Mike
concluded.

</p><p>
"Sounds good, Mike. If we've arrived at L5, I'll start calibrating", James
said. He sipped at a mug of coffee, and started inputting models into the
computer on his desk.

</p><p>
While James crunched the coordinates, Mike confirmed that the probe had reached
the Lagrange point. It had been quite easy for HT to slingshot across to the
fifth point, where the Earth had been two months ago; little fuel had been
expended on the journey, and the majority was going to be used in braking
towards the gravitational stability point.

</p><p>
Theory held that at L5 (and conversely, at L4), one could plant a probe or
satellite and have it stay there, rather than floating in towards the Earth or
Sun. It would, of course, be moving at a speed equal to the Earth, since the
Lagrange points moved with the Earth as it orbited; however, this would be the
only speed required for calculations. That was why James had originally asked
for one of these points to be used as the basis of the experiment.

</p><p>
Before too long, James indicated that he had calibrated things, and they were
ready. Mike had adjusted one of the lunar 'scope feeds to show HT, in close-up,
as it was parked at L5; the other 'scope was pointed at L4, on the other side
of Earth's orbit, where it would be in two months' time. Mike sent out the
signal for the probe to begin spinning up.

</p><p>
"We'll be able to see the spin-up in ahout two minutes' time, given signal
delays. Should be another minute before things are at full speed", Mike
stated. "Let's hope you've got all the gravities right, James."

</p><p>
"We're lucky that Jupiter is on the other side of the Sun right now, otherwise
things would've got quite complicated with the coordinate calculation. As it
is, we should end up more or less as expected", James replied.

</p><p>
As James continued with his coffee, HT returned that it was fully spun up.

</p><p>
"Drive?" Mike asked over the comm.

</p><p>
"Reporting 100%, caps are full. Settings programmed in; we're ready down
here."
</p><p>

"Alright; fire it up."

</p><p>
Nothing happened; not immediately, at least. The telescopes still showed HT
hanging in place at L5, for a minute or so. The tension mounted in the command
room; James had a niggling sense that something might be off on his
calculation, and HT would be destroyed or vanish never to be seen again. As
quickly as the thought surfaced, it was discounted: a bright point flashed on
the screen, and HT was gone. It had taken a minute for light to come from the
L5 point to the lunar telescopes, and another few seconds for the images to
relay to the command centre. HT was away.

</p><p>
A bright flash on the other monitor, and HT appeared. The stars behind it were
different, however: the probe was now at L4, a full twenty million miles away.
These images were also coming from the Moon, which meant that the move between
Lagrange points had been almost instantaneous.

</p><p>
"What's that, 0.2 AU in half a second? Pretty quick, James", Mike laughed.

</p><p>
"And right where we wanted it, Mike. Let's get HT home and have a look at the
insides; I wanna see what hyperspace did to my bacterial samples."
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Parsing the DIME Message Format</title>
 <link href="https://imrannazar.com/articles/parsing-dime-messages" rel="alternate" type="text/html" title="Parsing the DIME Message Format" />
 <id>https://imrannazar.com/articles/parsing-dime-messages</id>
 <summary>If a SOAP web service requests in a complex response, where more than one file has to be returned, an encoding format has to be used to fit the files into one message. One of the more common formats is Microsoft DIME, used by Jasper Reports and other services. This article looks into how a DIME message can be parsed, and the files pulled out to work with.</summary>
 <category term="Articles" />
 <published>Wed, 29 Jul 2009 19:22:40 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Talking to web interfaces with SOAP has been made very simple in PHP, thanks to the inclusion of a SOAP module in the standard PHP 5 build. Having the functionality of a SOAP client built-in means it's very quick and easy to call an interface through either the raw RPC or the provided WSDL, which can return XML or plain text values.</p>
<p>The trouble starts to come in when the interface wishes to return a complicated result: a file that isn't XML or plain text, or a series of files in the same return package. There are various encodings used in the transfer of complex SOAP results; one of the more common is Direct Internet Message Encapsulation, or DIME.</p>
<h2>The DIME Format</h2>
<p>DIME is essentially a wrapper over MIME, allowing multiple MIME parts to be sent in one package. The format was developed by Microsoft as a draft standard, and was adopted by a good number of SOAP interfaces before the official data standard was drawn up. The concept of the format is very simple: a series of files, either XML or binary data, with a short header on each file.</p>
<p>Each part can be marked as the first and/or last part of the message, and the type of data it contains can also be marked as XML or binary. Being a Microsoft standard, the definition of the header for each part involves bitfields and binary fiddling. There's also scope provided for extensions to the DIME format, but none of these were ever defined, so you're unlikely to find any messages with options filled in.</p>
<figure>
 <table>
  <thead><tr><th>Field</th><th>Length</th><th>Description</th></tr></thead>
  <tbody>
   <tr><td>Version</td><td>5 bits</td><td>DIME format version (always 1)</td></tr>
   <tr><td>First Record</td><td>1 bit</td><td>Set if this is the first part in the message</td></tr>
   <tr><td>Last Record</td><td>1 bit</td><td>Set if this is the last part in the message</td></tr>
   <tr><td>Chunk Record</td><td>1 bit</td><td>This file is broken into chunked parts</td></tr>
   <tr><td>Type Format</td><td>4 bits</td><td>Type of file in the part (1 for binary data, 2 for XML)</td></tr>
   <tr><td><em>Reserved</em></td><td>4 bits</td><td>(Classic Microsoft)</td></tr>
   <tr><td colspan="3"><strong>The following fields are big-endian numbers</strong></td></tr>
   <tr><td>Options Length</td><td>2 bytes</td><td>Length of the "options" field</td></tr>
   <tr><td>ID Length</td><td>2 bytes</td><td>Length of the "ID" or "name" field</td></tr>
   <tr><td>Type Length</td><td>2 bytes</td><td>Length of the "type" field</td></tr>
   <tr><td>Data Length</td><td>4 bytes</td><td>Size of the included file</td></tr>
   <tr><td colspan="3"><strong>The following fields are variable-length, and padded to the next 4-byte boundary</strong></td></tr>
   <tr><td>Options</td><td colspan="2">Part-specific option data, if any is defined (safely answer "no")</td></tr>
   <tr><td>ID</td><td colspan="2">Name of the file/part</td></tr>
   <tr><td>Type</td><td colspan="2"><em>If typeformat is 1:</em> MIME type of the part data<br><em>If typeformat is 2:</em> URI of the DTD file for the XML enclosed</td></tr>
   <tr><td>Data</td><td colspan="2">The file</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: DIME part header</figcaption>
</figure>
<p>As you can see, it's possible for a DIME message to contain only one part, by marking it as both the first and the last. Each part follows directly on from the last, so it's easy enough to run through a DIME message in a loop, working out the position of each part by finding out where you end up after adding up the sizes of the four sections and the header (which is 12 bytes).</p>
<p>One complication of the format is that each section in a part (options, ID, type, data) is padded, so that it takes up an even multiple of 4 bytes; this is generally done by filling the gap with "0" bytes. For example, if the type of the file was given as "text/html", you'd end up with the following in the message:</p>
<samp>
 <h3>Padded "type" field</h3>
 <pre><s>74 65 78 74 2F 68 74 6D 6C</s> <var>00 00 00</var> -- text/html</pre>
</samp>
<p>The green area above is the field data itself, defined by the header as 9 bytes long. The next multiple of 4 from there is 12, so three bytes of padding are added to push the field to an even boundary; these bytes are not counted as part of the field data.</p>
<h2>Reading DIME messages in PHP</h2>
<p>Using the <a href="http://imrannazar.com/The-Structure-Pattern">structure pattern</a> in PHP, it's quite a simple endeavour to build a class capable of reading in DIME messages and extracting the parts. The basis of this is the DIMERecord structure.</p>
<samp>
 <h3>DIMERecord: Structure holding information about a DIME part</h3>
 <pre><kbd>class</kbd> DIMERecord
{
    <kbd>public</kbd> $version;
    <kbd>public</kbd> $first;
    <kbd>public</kbd> $last;
    <kbd>public</kbd> $chunked;
    <kbd>public</kbd> $type_format;
    <kbd>public</kbd> $options;
    <kbd>public</kbd> $id;
    <kbd>public</kbd> $type;
    <kbd>public</kbd> $data;
}</pre>
</samp>
<p>Filling in this structure can be done from another class, acting as the DIME parser itself. It's this class which holds the array of DIMERecords referencing the parts.</p>
<samp>
 <h3>DIME: Building the record array</h3>
 <pre><kbd>class</kbd> DIME
{
    <kbd>const</kbd> TYPE_BINARY = <var>1</var>;
    <kbd>const</kbd> TYPE_XML = <var>2</var>;

    <kbd>public</kbd> $records;

    <kbd>function</kbd> __construct($input)
    {
	$<kbd>this</kbd>-&gt;records = <kbd>array</kbd>();
	$pos = <var>0</var>;

	<kbd>do</kbd>
	{
	    $r = <kbd>new</kbd> DIMERecord;

	    <s>// Shift out bitfields for the first fields</s>
	    $b = <kbd>ord</kbd>($input[$pos++]);
	    $r-&gt;version     = ($b&gt;&gt;<var>3</var>) &amp; <var>31</var>;
	    $r-&gt;first       = ($b&gt;&gt;<var>2</var>) &amp; <var>1</var>;
	    $r-&gt;last        = ($b&gt;&gt;<var>1</var>) &amp; <var>1</var>;
	    $r-&gt;chunked     = $b &amp; <var>1</var>;
	    $r-&gt;type_format = (<kbd>ord</kbd>($input[$pos++]) &gt;&gt; <var>4</var>) &amp; <var>15</var>;

	    <s>// Fetch big-endian lengths</s>
            $lengths = <kbd>array</kbd>();
            $lengths[<var>'options'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'options'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'id'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'id'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'type'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'type'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'data'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>24</var>;
            $lengths[<var>'data'</var>] |= (<kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>16</var>);
            $lengths[<var>'data'</var>] |= (<kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>);
            $lengths[<var>'data'</var>] |= <kbd>ord</kbd>($input[$pos++]);

	    <s>// Read in padded data</s>
	    <kbd>foreach</kbd>($lengths <kbd>as</kbd> $lk =&gt; $lv)
	    {
	        $r-&gt;$lk = <kbd>substr</kbd>($input, $pos, $lv);
		$pos += $lv;

		if($lv &amp; <var>3</var>)
		    $pos += (<var>4</var>-($lv &amp; <var>3</var>));
	    }

	    $this-&gt;records[] = $r;
	}
	<kbd>while</kbd>($pos &lt; <kbd>strlen</kbd>($input));
    }
}</pre>
</samp>
<h2>Chunking: Breaking up files across parts</h2>
<p>The DIME standard also accommodates the ability to break up a file across multiple parts, in case the client or server don't have the processing power to fill out a header for a big file all at once. Parsing a chunked file from its parts involves checking the "chunked" bit for the part being checked, and the part before it, making a decision based on the values:</p>
<figure>
 <table>
  <thead><tr><th>This part chunked?</th><th>Previous part chunked?</th><th>Action</th></tr></thead>
  <tbody>
   <tr><td>No</td><td>No</td><td>This is a normal file; save</td></tr>
   <tr><td>Yes</td><td>No</td><td>This is the first chunk part; start a data buffer</td></tr>
   <tr><td>Yes</td><td>Yes</td><td>This is a continuation chunk; append to the data buffer</td></tr>
   <tr><td>No</td><td>Yes</td><td>This is the last chunk part; append to the data buffer and save</td></tr>
  </tbody>
 </table>
 <figcaption>Table 2: Actions taken for a chunked part</figcaption>
</figure>
<p>The type and id for the file are taken from the first chunk; any chunks after that have these fields set to zero, and have to be ignored. Implementing chunking involves extending the parser function, so that it holds a series of files as well as a series of records.</p>
<samp>
 <h3>DIMEFile: Unchunking files</h3>
 <pre><kbd>class</kbd> DIMEFile
{
    <kbd>public</kbd> $type_format;
    <kbd>public</kbd> $type;
    <kbd>public</kbd> $id;
    <kbd>public</kbd> $data;
}

<kbd>class</kbd> DIME
{
    <kbd>const</kbd> TYPE_BINARY = <var>1</var>;
    <kbd>const</kbd> TYPE_XML = <var>2</var>;

    <kbd>public</kbd> $records;
    <kbd>public</kbd> $files;

    <kbd>function</kbd> __construct($input)
    {
	$<kbd>this</kbd>-&gt;records = <kbd>array</kbd>();
	$pos = <var>0</var>;

        <s>// Break out parts from the message string</s>
	<kbd>do</kbd>
	{
	    $r = <kbd>new</kbd> DIMERecord;

	    <s>// Shift out bitfields for the first fields</s>
	    $b = <kbd>ord</kbd>($input[$pos++]);
	    $r-&gt;version     = ($b&gt;&gt;<var>3</var>) &amp; <var>31</var>;
	    $r-&gt;first       = ($b&gt;&gt;<var>2</var>) &amp; <var>1</var>;
	    $r-&gt;last        = ($b&gt;&gt;<var>1</var>) &amp; <var>1</var>;
	    $r-&gt;chunked     = $b &amp; <var>1</var>;
	    $r-&gt;type_format = (<kbd>ord</kbd>($input[$pos++]) &gt;&gt; <var>4</var>) &amp; <var>15</var>;

	    <s>// Fetch big-endian lengths</s>
            $lengths = <kbd>array</kbd>();
            $lengths[<var>'options'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'options'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'id'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'id'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'type'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>;
            $lengths[<var>'type'</var>] |= <kbd>ord</kbd>($input[$pos++]);

            $lengths[<var>'data'</var>]  = <kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>24</var>;
            $lengths[<var>'data'</var>] |= (<kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>16</var>);
            $lengths[<var>'data'</var>] |= (<kbd>ord</kbd>($input[$pos++]) &lt;&lt; <var>8</var>);
            $lengths[<var>'data'</var>] |= <kbd>ord</kbd>($input[$pos++]);

	    <s>// Read in padded data</s>
	    <kbd>foreach</kbd>($lengths <kbd>as</kbd> $lk =&gt; $lv)
	    {
	        $r-&gt;$lk = <kbd>substr</kbd>($input, $pos, $lv);
		$pos += $lv;

		if($lv &amp; <var>3</var>)
		    $pos += (<var>4</var>-($lv &amp; <var>3</var>));
	    }

	    $this-&gt;records[] = $r;
	}
	<kbd>while</kbd>($pos &lt; <kbd>strlen</kbd>($input));

        <s>// Unchunk records into files, as required</s>
	$previous_chunk = <var>0</var>;
	<kbd>foreach</kbd>($<kbd>this</kbd>-&gt;records <kbd>as</kbd> $r)
	{
	    <kbd>if</kbd>(!$r-&gt;chunked)
	    {
	        <kbd>if</kbd>(!$previous_chunk)
		{
		    <s>// Normal part</s>
		    $f = <kbd>new</kbd> DIMEFile;
		    $f-&gt;type_format = $r-&gt;type_format;
		    $f-&gt;type        = $r-&gt;type;
		    $f-&gt;id          = $r-&gt;id;
		    $f-&gt;data        = $r-&gt;data;

		    $<kbd>this</kbd>-&gt;files[] = $f;
		}
		<kbd>else</kbd>
		{
		    <s>// Final chunk</s>
		    $f-&gt;data .= $r-&gt;data;
                    $<kbd>this</kbd>-&gt;files[] = $f;
		}
	    }
	    <kbd>else</kbd>
	    {
	        <kbd>if</kbd>(!$previous_chunk)
		{
		    <s>// First chunk</s>
		    $f = <kbd>new</kbd> DIMEFile;
		    $f-&gt;type_format = $r-&gt;type_format;
		    $f-&gt;type        = $r-&gt;type;
		    $f-&gt;id          = $r-&gt;id;
		    $f-&gt;data        = $r-&gt;data;
		}
		<kbd>else</kbd>
		{
		    <s>// Continuation</s>
		    $f-&gt;data .= $r-&gt;data;
		}
	    }
	    $previous_chunk = $r-&gt;chunked;
	}
    }
}</pre>
</samp>
<h2>Example: Requesting a Jasper report</h2>
<p>The JasperServer reporting service uses SOAP to allow requests for reports, and a DIME-encoded message to return the status message XML and the report itself as one result. The details for our example JasperServer are as follows:</p>
<figure>
 <table>
  <tr><td>WSDL URI</td><td>http://localhost:8080/jasperserver/services/repository?wsdl</td></tr>
  <tr><td>Namespace</td><td>http://www.jaspersoft.com/namespaces/php</td></tr>
  <tr><td>Request</td><td>runReport</td></tr>
  <tr><td>Report URI</td><td>/reports/inventory_list</td></tr>
 </table>
 <figcaption>Table 3: SOAP access details for an example JasperServer</figcaption>
</figure>
<p>Using these access details, and passing them through PHP's native SOAP client, it's a simple matter to retrieve the DIME-encoded return message.</p>
<samp>
 <h3>SOAP client code to retrieve the report</h3>
 <pre>$request =
<var>'&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;request operationName="<kbd>runReport</kbd>" locale="en"&gt;
 &lt;argument name="RUN_OUTPUT_FORMAT"&gt;XLS&lt;/argument&gt;
 &lt;argument name="USE_DIME_ATTACHMENTS"&gt;&lt;![CDATA[1]]&gt;&lt;/argument&gt;
 &lt;resourceDescriptor name="" wsType="reportUnit" uriString="<kbd>/reports/inventory_list</kbd>" isNew="false"&gt;
  &lt;label&gt;&lt;/label&gt;
 &lt;/resourceDescriptor&gt;
&lt;/request&gt;'</var>;

$c = <kbd>new</kbd> SoapClient(
    <var>'http://localhost:8080/jasperserver/services/repository?wsdl'</var>,
    <kbd>array</kbd>(<var>'trace'</var> =&gt; <kbd>true</kbd>));

<kbd>try</kbd>
{
    $c-&gt;__soapCall(
        <var>'runReport'</var>,
        <kbd>array</kbd>(<var>'request'</var> =&gt; $request),
	<kbd>array</kbd>(<var>'namespace'</var> =&gt; <var>http://www.jaspersoft.com/namespaces/php</var>));
}
<kbd>catch</kbd>(SoapFault $cf)
{
    <s>// A DIME-encoded message has no text, generating an exception
    // Parse out the traced response, and get the file from there
    // Response should be one XML file, and one binary</s>

    $dp = <kbd>new</kbd> DIME($c-&gt;__getLastResponse());
    <kbd>foreach</kbd>($dp-&gt;files <kbd>as</kbd> $f)
    {
        <kbd>if</kbd>($f-&gt;type_format == DIME::TYPE_BINARY)
	{
	    <kbd>header</kbd>(<var>'Content-type: '</var>.$f-&gt;type);
	    <kbd>header</kbd>(<var>'Content-disposition: attachment; filename="'</var>.$f-&gt;id.<var>'"'</var>);
	    <kbd>echo</kbd> $f-&gt;data;
	}
    }
}</pre>
</samp>
<p>That's how you can use the DIME parser I've introduced here, to pull data out of a DIME-encoded SOAP response. As can be seen from the sample invocation here, all that's needed is to make a new DIME object from the message string, and check the array of files that's generated as a result.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, Jul 2009</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Rebuilding Your Leg After Shooting Yourself in the Foot</title>
 <link href="https://imrannazar.com/articles/rebuilding-your-leg" rel="alternate" type="text/html" title="Rebuilding Your Leg After Shooting Yourself in the Foot" />
 <id>https://imrannazar.com/articles/rebuilding-your-leg</id>
 <summary>At some point, most developers have come across &#039;Shooting yourself in the foot&#039;, the comparison of how different programming languages would implement the process of firing a gun at your foot. This article assumes success, and the lack of a significant portion of your leg; Part Two looks at how to rebuild your leg, in various languages.</summary>
 <category term="Articles" />
 <published>Thu, 04 Jun 2009 14:02:19 +0000</published>
 <content type="text/html"><![CDATA[
   <div style='position:absolute;top:280px;left:50px;padding:0.25em 0 0 0.25em;border:1px solid #bbb'>
 <script type='text/javascript'>
 digg_url='http://digg.com/programming/Shooting_Yourself_in_the_Foot_Part_Two';
 digg_bgcolor='transparent';
 digg_skin='compact';
 </script><script type='text/javascript' src='http://digg.com/api/diggthis.js'></script></div>
<dl>
<dt>C</dt>
<dd>You build a new leg.</dd>
<dt>ASM</dt>
<dd>You redefine every cell in the leg, and all the inter-cell bonds; when you're done, watch your leg vanish at the first segfault.</dd>
<dt>C++</dt>
<dd>Nobody understands how you did it, but you've created an iron plated leg that runs so fast that it's essentially useless, and you walk in circles for hours.</dd>
<dt>C#</dt>
<dd>You build a leg, and it works wonderfully, but only within the city limits of Seattle.</dd>
<dt>Ruby</dt>
<dd>You build 15 more legs, and four more bodies to carry them around. For redundancy.</dd>
<dt>Objective C</dt>
<dd>You buy a new chrome leg, at great expense, and find it won't work without a chrome hip.</dd>
<dt>Objective-C on iPhone</dt>
<dd>You write an application that heals your leg when you shake it and sell it for $5. It also acts as a flashlight and makes fart noises when you use it.</dd>
<dt>Perl</dt>
<dd>You spend two days attempting to work with the Leg::Prostethic module, before running your previous C code through encryption and executing the result. A leather couch appears.</dd>
<dt>Prolog</dt>
<dd>You define your leg as healed, and wait four years for the leg to build itself.</dd>
<dt>AppleScript</dt>
<dd>A basic, cylindrical leg appears, which just barely works through a series of jerky, childlike movements.</dd>
<dt>Brainfuck</dt>
<dd>You spent nearly a month creating the replacement leg, everyone pats you on the back and you feel pretty good about yourself, but you somehow wonder if there was an easier way.</dd>
<dt>Malbolge</dt>
<dd>You spend the rest of your life rebuilding half a leg, but you somehow have to divide it by 57 before it can be finished.</dd>
<dt>Piet</dt>
<dd>You paint a picture of a leg, and then execute it. A leather couch appears.</dd>
<dt>Haskell</dt>
<dd>You heal your leg in one line. You then write 10 pages of LaTeX documentation on how you could have healed your leg more efficiently.</dd>
<dt>Befunge</dt>
<dd>With a good editor, your leg takes mere minutes to prototype, however you'll be improving it for the rest of your life to get it down to small enough to be usable.</dd>
<dt>Java <em>(modified 2009-06-05)</em></dt>
<dd>After discovering the lack of a built-in library for legs, you spend 8 hours trying to write factory patterns for human, animal and robot legs, then instantiate a new leg. The stump of the old leg loiters around for a while before being collected.</dd>
<dt>Java on Android <em>(added 2015-04-25)</em></dt>
<dd>Google builds and attaches your leg for you, but collects and records all your vital signs as stipulated under section 83.5 of the EULA you signed.</dd>
<dt>Lisp</dt>
<dd>You attach the leg bone to the hip bone, which is attached to the leg bone, which is attached to the hip bone...</dd>
<dt>COBOL</dt>
<dd>PROCEDURE DIVISION. WRITE ESSAY IN REGARD TO CONSTRUCTION OF NEW LEG. RUN.</dd>
<dt>Javascript</dt>
<dd>You spend a few hours building an array of pieces of leg, and a few weeks playing with toolkits that can slide pieces of leg around in all sorts of ways.</dd>
<dt>PHP<dt>
<dd>You can't remember whether the function order requires (hip, leg, ankle) or (ankle, leg, hip). Eventually through trial and error, you have a leg which works fine on tarmac but doesn't understand grass.</dd>
<dt>HTML</dt>
<dd>You build a framework for a leg, and you wake up in the morning with it blinking.</dd>
<dt>CSS</dt>
<dd>You attach a new leg to the hip and float it in the proper direction, but your feet are also attached to your hips because they haven't been cleared below the legs.</dd>
<dt>Scheme</dt>
<dd>You can only build a leg-1, so you can either have a leg to stand on or have something to give you a leg up, but not both.</dd>
<dt>SQL</dt>
<dd>You attempt to clean up the stump of your leg by deleting it, but you forget to specify which limb to delete; now you have no arms or legs.</dd>
<dt>Bash</dt>
<dd>You try to rm -r /limbs/leg/right/stump, but hit enter instead of tab after rm -r / and disappear.</dd>
<dt>Pascal</dt>
<dd>You build a leg module, just in time to learn that Modula-2 has legs built into the standard library.</dd>
<dt>BASIC</dt>
<dd>Your new leg looks perfectly fine, but doesn't work until you tattoo numbers down the side of the shin.</dd>
<dt>JCL</dt>
<dd>You spend weeks crafting a build mechanism for your leg, and submit it to the mainframe, to find a syntax error. Only then do you find, that you don't understand the code any more.</dd>
<dt>Erlang</dt>
<dd>You spawn a process to fix your leg, and a supervisor process to build more new legs just in case. The supervisor attaches all your new legs to your head, because your hip is an immutable structure.</dd>
<dt>Python <em>(modified 2015-04-24)</em></dt>
<dd><code>from __future__ import leg</code></dd>
<dt>Fortran <em>(modified 2009-06-17)</em></dt>
<dd>You build a new leg, and spend the rest of your life improving it in small increments until you can leap tall buildings. Unfortunately, no-one cares.</dd>
<dt>CUDA <em>(added 2009-06-05)</em></dt>
<dd>You make 10,000 tiny legs which enable you to run at thirty miles an hour, but they only work on astroturf.</dd>
<dt>Lua <em>(added 2009-06-05)</em></dt>
<dd>You find that you can only emulate a new leg as userdata with a metatable the size of the moon. Surprisingly, this works quite well if you upgrade your brain at the same time.</dd>
<dt>POVRay <em>(added 2009-06-08)</em></dt>
<dd>You design a new leg from basic geometric shapes, and texture it in reflective Perlin noise. Because it looks cooler that way.</dd>
<dt>D <em>(added 2009-06-08)</em></dt>
<dd>You build a new leg. You forget that the Makefile specifies omission of bounds checking, so attaching the new leg extends it into your torso, replacing many vital organs.</dd>
<dt>Matlab <em>(added 2009-06-17)</em></dt>
<dd>You meticulously formulate the components of your new leg, and then build it. A graph of your leg's kinetic energy output appears.</dd>
<dt>Qubit C <em>(added 2009-06-17)</em></dt>
<dd>You set out to create a new leg, which would explain the extra leg you sprouted last week. A leather couch appears.</dd>
<dt>Whitespace <em>(added 2009-06-17)</em></dt>
<dd><pre>                                                               
                                                         
                               
                                                     
                                                                 
                                                       </pre></dd>
<dt>Win32 API <em>(added 2015-04-24)</em></dt>
<dd>Microsoft hands you a new leg, but it keeps randomly cramping up. Every diagnosis only comes up with a strange number and "The leg is incorrect". Your only option is to go home and sleep it off.</dd>
<dt>Visual Basic <em>(added 2015-04-24)</em></dt>
<dd>You call the doctor's office to build you a new a leg, but find out that it comes with an incantation tattoo'd onto it that causes it to never stop running. The unfamiliar phrase reads: <code>On Error Resume Next</code></dd>
<dt>Rust <em>(added 2015-04-24)</em></dt>
<dd>You make a new leg without any trouble but when you try to attach it the compiler complains that that it doesn't live long enough.</dd>
</dl>
<p class="ft">With thanks to: letusgothen, TehLaser, VoidBoi, jercos, matja, apathy, asonge, Ended, tobias104, <a href="http://www.emyrderfel.co.uk/">Emu*</a>, MHD, lulzfish, Ysn, maafy6, RoadieRich.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Vanilla JavaScript Slideshows</title>
 <link href="https://imrannazar.com/articles/vanilla-js-slideshows" rel="alternate" type="text/html" title="Vanilla JavaScript Slideshows" />
 <id>https://imrannazar.com/articles/vanilla-js-slideshows</id>
 <summary>Many developers state that modern JavaScript effects, such as slide-shows and news tickers, can only be viably achieved using frameworks such as jQuery and Dojo. This article sets out to demonstrate that it is in fact a simple affair to construct a slideshow using JavaScript and DOM manipulation, without the need for such frameworks.</summary>
 <category term="Articles" />
 <published>Wed, 03 Jun 2009 19:18:57 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#content .sshow-container {
  width: 440px;
  margin: 0 auto;
  border: 1px solid #555;
}

.sshow-container a {
  height: 200px;
  width: 20px;
  float: left;
  display: block;
  text-align: center;
  line-height: 200px;
  text-decoration: none;
  font-size: 1.5em;
  font-weight: bold;
}

#sshow {
  margin: 5px auto;
  line-height: 1.1em;
  overflow: hidden;
  position: relative;
  float: left;
}

#sshow ul {
  list-style: none inside;
  position: relative;
}

#sshow li {
  position: absolute;
  top: 0;
}

#sshow dl {
  margin: 5px;
  font-size: 0.7em;
}

#sshow dt {
  font-weight: bold;
}

#sshow dd {
  margin-bottom: 1em;
}

</style>
<p>Many sites introduce a dynamic element to their content by including a "slide-show" subsection: a list of items or pictures which can be scrolled through and viewed in portions, and which repeats to the first item when the last item is visible. An example of such a slide-show is show below.</p>
<figure>
 <div class="sshow-container">
  <script type="text/javascript">
var News = { id: 'sshow', step: 5, rate: 10, height: 200, itemwidth: 200, blockwidth: 400, fullwidth: 800 };

News.init = function() {
	document.getElementById(News.id).style.height = News.height+'px';
	document.getElementById(News.id).style.width = News.blockwidth+'px';

	var content = document.getElementById(News.id).getElementsByTagName('ul')[0];
	content.style.width = News.fullwidth;
	var width = News.fullwidth;
	var clone = content.cloneNode(true);
	clone.style.width = width + 'px';
    clone.style.left = '-40px';
	News.pos = 0;
	News.curtravel = 0;
	News.width = width;
	News.content = content;
	content.appendChild(clone);

	var dt = content.getElementsByTagName('li');
	News.dtpos = new Array(dt.length);
	for(i=0; i<dt.length; i++)
	{
		News.dtpos[i] = i*News.itemwidth;
		dt[i].style.left = i*News.itemwidth+'px';
		dt[i].style.width = News.itemwidth+'px';
	}

	document.getElementById('left').onclick=function(){News.scroll(News.step);return false;}
	document.getElementById('right').onclick=function(){News.scroll(-News.step);return false;}
};

News.scroll = function(lr) {
	News.timer = setTimeout(function(){News.scroll(lr);}, rate);

	var pos = News.pos;
	var rate = News.rate;
	var dt = document.getElementById(News.id).getElementsByTagName('ul')[0].getElementsByTagName('li');
	if(lr > 0)
	{
		pos += News.step;
		if (pos >= News.fullwidth) pos = 0;
		for(i=0; i<News.dtpos.length; i++)
		{
			if(pos >= 0)
			{
				dtp = i*News.itemwidth;
				if(dtp+pos>News.blockwidth) dtp-=News.fullwidth;
				if(dtp+pos<-(News.blockwidth+News.itemwidth)) dtp+=News.fullwidth;
				dt[i].style.left = dtp+'px';
			}
		}
	}
	else
	{
		pos -= News.step;
		if (pos <= -News.width) pos = 0;
		for(i=0; i<News.dtpos.length; i++)
		{
			if(pos <= 0)
			{
				dtp = i*News.itemwidth;
				if(dtp+pos<-News.itemwidth) dtp+=News.fullwidth;
				dt[i].style.left = dtp+'px';
			}
		}
	}
	News.curtravel += News.step;
	if(News.curtravel >= News.itemwidth)
	{
		News.curtravel = 0;
		News.stopscroll();
	}
	News.content.style.left = pos + 'px';
	News.pos = pos;
};

News.stopscroll = function() {
	clearTimeout(News.timer);
};
  </script>
  <a href="#" id="left">&laquo;</a>
  <div id='sshow'>
   <ul>
    <li>
     <dl>
      <dt>Al-Qaeda 'kills British hostage'</dt>
      <dd>03 June 2009 09:47</dd>
      <dd>Downing Street says there is "strong reason to believe" that a British citizen has been killed by al-Qaeda militants in Africa.</dd>
     </dl>
    </li>
    <li>
     <dl>
      <dt>Government still working - Harman</dt>
      <dd>03 June 2009 10:07</dd>
      <dd>Harriet Harman hits back at claims the government is in its "death throes" after ministers' decisions to stand down.</dd>
     </dl>
    </li>
    <li>
     <dl>
      <dt>Broadband 'essential' to UK</dt>
      <dd>03 June 2009 02:24</dd>
      <dd>Consumers consider broadband internet as important a utility as water or electricity, a government advisory panel finds.</dd>
     </dl>
    </li>
    <li>
     <dl>
      <dt>Obama embarks on Mid-East mission</dt>
      <dd>03 June 2009 04:03</dd>
      <dd>President Barack Obama heads to the Middle East on a visit aimed at increasing US engagement with the Islamic world.</dd>
     </dl>
    </li>
   </ul>
  </div>
  <a href="#" id="right">&raquo;</a>
  <script type="text/javascript">
window.onload = News.init;
  </script>
 <div style="clear:both"></div>
 </div>
 <figcaption>Figure 1: Slide-show in use as a news ticker</figcaption>
</figure>
<p>In the above sample, the window is controlled by left and right anchors, which each give a direction for the window to move in by one step. It may seem complicated to implement such a slide-show, but this article will show you the basic pieces of code that go into making the slide-show work.</p>
<h2>Viewing the world though a window</h2>
<p>In order for the slide-show to operate, it's important to conceptualise what must be achieved. Each item in the section is joined horizontally to the next, to form a line of items. The user will see this line through a "window" which slides over the line, making a small portion visible.</p>
<figure>
 <img src="/content/img/js-scroll-window.png" alt="Window over the items">
 <figcaption>Figure 2: Items seen through a window</figcaption>
</figure>
<p>The task of the slide-show is to control where this window lies, and when to move it. This can be achieved through simple use of HTML and JavaScript: a DIV block will act as the window, and the list of items is contained within the window.</p>
<samp>
 <h3>HTML for window and list</h3>
 <pre>&lt;div id="window" style="overflow:hidden"&gt;
 &lt;ul&gt;
  &lt;li&gt;&lt;img src="item1.jpg"&gt;&lt;/li&gt;
  &lt;li&gt;&lt;img src="item2.jpg"&gt;&lt;/li&gt;
  &lt;li&gt;&lt;img src="item3.jpg"&gt;&lt;/li&gt;
  &lt;li&gt;&lt;img src="item4.jpg"&gt;&lt;/li&gt;
  &lt;li&gt;&lt;img src="item5.jpg"&gt;&lt;/li&gt;
 &lt;/ul&gt;
&lt;/div&gt;</pre>
</samp>
<p>The inline style placed on the window DIV demonstrates what will occur if the window is set to be a smaller width than the list contained within: the remainder of the list will be cut-off, and hidden from view.</p>
<h2>Moving the window</h2>
<p>In order to move the window over the list of items, repeated small steps must be taken: moving the window in one operation will result in a simple change of view, as opposed to the desired slide. This effect of repeated steps can be achieved by the judicious use of timeouts: the function responsible for making a small step sets a timer which will, after a short while, run the same function again to make the next step.</p>
<p>For this to work properly, the function must be able to detect when a full item has been scrolled into view, and it's time to stop moving further. In this article, I'll assume that the items in the list are all the same width, and that this width has been defined for the JavaScript function; it's possible, though more time-consuming, to record the positions of the list items in relation to each other, and detect the edge of an item by checking the window position against these item positions.</p>
<samp>
 <h3>Moving the window over the list</h3>
 <pre>timestep = 50;
pos = 0;
posstep = 4;
curtravel = 0;

step = function()
{
  timer = setTimeout(function(){step();}, timestep);
  curtravel += posstep;
  if(curtravel &gt;= itemwidth)
  {
    curtravel = 0;
    clearTimeout(timer);
  }

  pos += posstep;
  if(pos &gt;= listwidth) pos = 0;
  document.getElementById('window').style.left = pos+'px';
};</pre>
</samp>
<p>Note that in the above code, the window movement code will detect whether the window has reached the end of the list; if so, it will wrap to the start, and the first item will again be displayed.</p>
<h2>Wrapping the list items</h2>
<p>A problem presents itself with this simple approach: when approaching the end of the list, blank areas are shown before the first item appears once more. This is because the window is being positioned such that a part of it is past the end of the list, whereas the first item of the list is (as expected) at the start.</p>
<figure>
 <img src="/content/img/js-scroll-nowrap.png" alt="Non-wrapping list">
 <figcaption>Figure 3: Window positioned past the end of the list</figcaption>
</figure>
<p>This issue can be alleviated by repositioning the items in the list, to allow for the first item to be rendered after the end of the list, and thus for the window to encapsulate the area while showing that the list is wrapping to the start. In order to do this, the items in the list must have their positions checked for each step through the movement of the window: if the item is positioned on the "wrong" end of the list to the window movement, it must be moved to the other side.</p>
<samp>
 <h3>CSS to allow for movement of list items</h3>
 <pre>#window ul {
  position: relative;
}

#window li {
  position: absolute;
}</pre>
 <h3>Step function including item repositioning</h3>
 <pre>step = function()
{
  /* Initialise a timer, to do the step after this one */
  timer = setTimeout(function(){step();}, timestep);

  /* Set the window's new position */
  pos += posstep;
  if(pos &gt;= listwidth) pos = 0;

  /* Check each item in the list, to see if it's outside the bounds of the window
     and if so, move it to the other side of the window to allow for scroll-in */
  items = document.getElementById('window').getElementsByTagName('ul')[0].getElementsByTagName('li');
  for(var i=0; i&lt;items.length; i++)
  {
    if(pos &gt;= 0)
    {
      itempos = i*itemwidth;
      if(itempos+pos &gt; windowwidth)
        itempos -= listwidth;

      if(iempos+pos &lt; -(windowwidth+itemwidth))
        itempos += listwidth;

      items[i].style.left = itempos+'px';
    }
  }

  /* Check if we're at the end of a scroll; if so, stop the timer */
  curtravel += posstep;
  if(curtravel &gt;= itemwidth)
  {
    curtravel = 0;
    clearTimeout(timer);
  }

  /* Set the new window position */
  document.getElementById('window').style.left = pos+'px';
};</pre>
</samp>
<h2>Moving both ways</h2>
<p>The above code allows for the window to move rightwards over the list, which corresponds to a visual effect of pushing the list off-screen to the left, and bringing more items on-screen from the right. It's important that the code also allow for items to be scrolled to the right, which would involve moving the window leftwards over the list. This can be achieved by modifying the step function somewhat, to include clauses for the reverse direction of travel.</p>
<samp>
 <h3>Step function allowing for reverse travel</h3>
 <pre>step = function(stepdir)
{
  timer = setTimeout(function(){step(stepdir);}, timestep);
  items = document.getElementById('window').getElementsByTagName('ul')[0].getElementsByTagName('li');

  if(stepdir &lt; 0)
  {
    /* Handle moving the window left; the same as before, but
       with all the comparison and addition signs flipped */
    pos -= posstep;
    if(pos &lt;= listwidth) pos = 0;

    for(var i=0; i&lt;items.length; i++)
    {
      if(pos &lt;= 0)
      {
        itempos = i*itemwidth;
        if(itempos+pos &lt; -listwidth)
          itempos += listwidth;

        items[i].style.left = itempos+'px';
      }
    }
  }
  else
  {
    /* Handle moving the window right; this code is the same as before */
    pos += posstep;
    if(pos &gt;= listwidth) pos = 0;

    for(var i=0; i&lt;items.length; i++)
    {
      if(pos &gt;= 0)
      {
        itempos = i*itemwidth;
        if(itempos+pos &gt; windowwidth)
          itempos -= listwidth;

        if(iempos+pos &lt; -(windowwidth+itemwidth))
          itempos += listwidth;

        items[i].style.left = itempos+'px';
      }
    }
  }

  curtravel += posstep;
  if(curtravel &gt;= itemwidth)
  {
    curtravel = 0;
    clearTimeout(timer);
  }

  document.getElementById('window').style.left = pos+'px';
};</pre>
</samp>
<p>Now all that must be remembered is that moving left entails a positive step direction, and that moving right is a negative step direction.</p>
<h2>Caveats and extensions</h2>
<p>In principle, it's quite easy to adapt this slideshow to travel vertically instead of horizontally. However, the fact that this system relies on a fixed width for each list item is a disadvantage when it comes to vertical travel: as can be seen in the above sample, items will differ in height depending on their content.</p>
<p>To alleviate this, the system previously mentioned can be employed: a list is maintained of the positions of the items in the list, and these are used to check the bounds of the window. If an item's initial position combined with the window's position is outside the window, this will force it to move to the other side of the list.</p>
<p>This system can easily be extended to allow for image slideshows, by changing the contents of the list to a list of images of the same width; be combining the images with anchors, a thumbnail slideshow can be created. Feel free to extend the code to your heart's content.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, 2009</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Highrise</title>
 <link href="https://imrannazar.com/scifi/highrise" rel="alternate" type="text/html" title="Sci-fi Shorts: Highrise" />
 <id>https://imrannazar.com/scifi/highrise</id>
 <summary>A man is sealed into an apartment for four days. Short story, science-fiction.</summary>
 <category term="Original Writings" />
 <published>Thu, 09 Apr 2009 20:32:21 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Ryan had been here before.
</p><p>
The place was palatable enough, if a bit lightweight: bed, shower, toilet
cubicle, microwave oven. The east-facing wall was a viewscreen, which he could
switch to transparent if he wanted to see what was going on outside, or to any
of the dozens of full-definition channel feeds. There was, however, no way for
him to talk to the outside: no terminals, no data sockets. Even his cellphone
didn't work in here: it didn't seem to be picking up a signal.
</p><p>
He was on the ground floor of an apartment block, in room 106. The block was
eight stories high, and there were eight apartments on each floor. This was
Borneo Block 1, based in the equatorial country of the same name, and was the
ideal spot to put such a place as this.
</p><p>
Some of the apartments were occupied by families, some by lone residents such
as himself; none were empty. And none could be opened from the inside; once
they were sealed from the outside, only an extraordinary emergency could open
the doors. That was hardly likely to happen here, with no other buildings
within five miles of the block.
</p><p>
It was a prison. A comfortable prison, with a short stay, but a prison none
the less.
</p><p>
Every resident of the block would be here for four days, after which time a
new list of tenants would be drawn up and moved in. Ryan had just moved in, so
he settled down on the bed, identical to the one in 303 where he'd been placed
last time, and flipped the viewscreen to Pacific News.
</p><p>
Four days later, it was time to leave. As Ryan stepped out of the shower, the
apartment door unsealed and opened by itself. He dressed quickly, and made to
leave. As he stepped out of the apartment, the door sealed itself shut again.
He was met by Paul, manager of the summer shift at Borneo Block.
</p><p>
"Welcome back, Ryan. How's Earth?"
</p><p>
"Still there," he replied.
</p><p>
The apartment block began to draw away from them both; as it retreated, Ryan
could see a blue border encroach on the edges of the block. The border got
larger as the block dwindled, and intrusions of white and brown appeared in
spots and wisps.
</p><p>
Ryan kept one eye on the apartment block as it fell back towards Earth, his
temporary home for what the space elevator engineers called Lift Time; four
days was the quickest comfortable journey up to orbit, but the block would
fall much more quickly with no residents to cater for.
</p><p>
"We've got some retensioning to do on Four, if you want to jump straight in,"
Paul stated. Ryan was a maintenance engineer for the Borneo elevator, and
cable tension was a part of his job.
</p><p>
"Let's get started, then."
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Go Northeast</title>
 <link href="https://imrannazar.com/scifi/go-northeast" rel="alternate" type="text/html" title="Sci-fi Shorts: Go Northeast" />
 <id>https://imrannazar.com/scifi/go-northeast</id>
 <summary>A man finds himself standing in an open field west of a white house, with a boarded front door. (There is a small mailbox here.) First published by &lt;a href=&#039;http://www.365tomorrows.com/&#039;&gt;365tomorrows.com&lt;/a&gt;; flash sci-fi.</summary>
 <category term="Original Writings" />
 <published>Sun, 05 Apr 2009 19:52:57 +0000</published>
 <content type="text/html"><![CDATA[
   <p>He found himself waking up in a field. There was nothing unusual about that;
he'd camped up in fields many times during his travels. Something was
different this morning, though. For one thing, he could feel the wind over his
face, and that meant he was in the open.
</p><p>
He opened his eyes. Expecting to see the dark green of his tent over him, he
found a blue sky, tinged with the orange of a rising sun. He was indeed in the
open, so where was his tent?
</p><p>
He sat up, rubbing his eyes, trying to focus. Around him, there was just
grass; it was an open field, and he was apparently asleep right in the middle.
He couldn't remember finding this field; even if he had picked this place to
sleep overnight, his tent would've been over him, and he'd be nearer the woods.
Maybe the tent blew away last night, but he couldn't see it now. He'd have to
find another at some point.
</p><p>
He looked behind him, and there was a house in the distance. With the sun
behind it, lying in its own shadow, the house looked stark. He could see,
though, that it was a wooden house. The walls were lime-washed, and it looked
like some of the windows were broken. The front door had been boarded over at
one point, but the board had fallen away on one side.
</p><p>
He felt himself being drawn to the house, for some reason. Maybe because the
side window was open just enough for one person to get through, though anything
useful was probably long gone. His plan was to head further south today; his
old map showed a village by the road, which might prove a good source of food
for the next couple of weeks.
</p><p>
He got up, and made ready to leave. Instead of heading south, he turned around
to face the house. He found himself walking towards the open window, as though
something was pushing him towards it; as though a command had been given.
</p><p>
<p><code>&gt; GO NORTHEAST</code></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Vanilla JavaScript Tab Controls</title>
 <link href="https://imrannazar.com/articles/vanilla-js-tabs" rel="alternate" type="text/html" title="Vanilla JavaScript Tab Controls" />
 <id>https://imrannazar.com/articles/vanilla-js-tabs</id>
 <summary>Tabs have always been one of the most useful elements of a user interface, allowing an interface designer to pack a lot of information into a small space by only showing a section at a time. This article explores the implementation of a tabbing interface using HTML and JavaScript, and goes on to look at pages where more than one set of tabs is used at the same time.</summary>
 <category term="Articles" />
 <published>Sun, 08 Mar 2009 23:10:21 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#tabs-ex {
  font-family: Arial, Helvetica, sans-serif;
  width: 95%;
  margin: 1em auto;
}
#tabs-ex ul.tablist {
  list-style: none inside;
  margin: 0;
  padding: 0;
}
#tabs-ex ul.tablist li {
  display: block;
  float: left;
  background: #ddd;
  border-top: 1px solid #ddd;
  border-bottom: 1px solid black;
  position: relative;
  bottom: -1px;
  padding: 0.5em;
  margin-right: 2px;
  cursor: pointer;
}
#tabs-ex ul.tablist li.tab_hi {
  background: white;
  border-left: 1px solid black;
  border-right: 1px solid black;
  border-top: 1px solid black;
  border-bottom: 1px solid white;
}
#tabs-ex div.tab {
  border: 1px solid black;
  clear: both;
  padding: 0.5em;
  background: white;
}
div.tab form {
  margin: 0 1em 0;
}

div.tab form fieldset {
  border: 0px solid black;
}

div.tab form legend {
  display: none;
}

div.tab form label {
  display: block;
  position: relative;
  line-height: 1.5em;
  margin-bottom: 0.5em;
}

div.tab form label.bad {
  color: red;
}

div.tab form input.submit {
  margin: 1em auto;
  display: block;
}

div.tab form label input {
  position: absolute;
  right: 0;
  width: 60%;
}

#tabs-ex p {
  padding-top: 1em;
  text-align: center;
}
</style>
<p>The most basic display elements on a HTML page are easy to understand:
paragraphs, headings and tables. Often, a page is broken up into sections where
each section contains these elements; these sections can be defined in the HTML
source as blocks. The problem that arises from this is how to display the
separate sections in an intuitive manner.</p>
<p>An example would be a login form, on which you can provide a username and
password to log in. Another section of the page provides a "forgot-password"
form, where an email address can be entered and a retrieval email sent. This
page may be written in two sections, as below.</p>
<samp>
 <h3>Two-section login form</h3>
 <pre>&lt;h2&gt;Login&lt;/h2&gt;
&lt;form action="/login" method="post"&gt;
 &lt;fieldset&gt;
  &lt;legend&gt;Provide login details&lt;/legend&gt;
  &lt;label for="user"&gt;Username:&lt;/label&gt;&lt;input type="text" name="username" id="user"&gt;
  &lt;label for="pass"&gt;Password:&lt;/label&gt;&lt;input type="password" name="password" id="pass"&gt;
  &lt;input type="hidden" name="do" value="login"&gt;
  &lt;input type="submit" name="go" value="Login"&gt;
 &lt;/fieldset&gt;
&lt;/form&gt;
&lt;h2&gt;Forgot Password&lt;/h2&gt;
&lt;form action="/login" method="post"&gt;
 &lt;fieldset&gt;
  &lt;legend&gt;Provide e-mail&lt;/legend&gt;
  &lt;label for="email"&gt;E-mail:&lt;/label&gt;&lt;input type="text" name="email" id="email"&gt;
  &lt;input type="hidden" name="do" value="forgot"&gt;
  &lt;input type="submit" name="go" value="Get Password"&gt;
 &lt;/fieldset&gt;
&lt;/form&gt;</pre>
</samp>
<p>Having these two forms directly in line with each other could cause some
confusion for the user. There are a few ways to alleviate this: bringing the
two forms alongside each other, for example, would allow a visual separation
of the two functions. The most effective display method in this situation,
however, is tabbing.</p>
<h2>The tab system</h2>
<p>It's very likely that you've come across tabs before: they've been used by
web browsers for many years as a way to display multiple pages in the same
browser window. There are two components to a tabbing system: the tab list
and the tab contents. Each entry in the tab list has an associated content
block: when a given entry in the tab list is selected, the content block for
that entry is displayed and the other content blocks are hidden away.</p>
<figure>
 <img src="/content/img/js-tabs-browser.png" alt="Browser tabs">
 <figcaption>Figure 1: Graphical tabs, in a web browser</figcaption>
</figure>
<p>In the above example, four separate pages are open in the same web browser
instance: the second is selected. As can be seen, it's obvious which tab is
selected, and which contents are being displayed as a result. Tabs aren't just
a graphical concept, however: they can be used equally well in a text-based
environment.</p>
<figure>
 <img src="/content/img/js-tabs-screen.png" alt="Screen tabs">
 <figcaption>Figure 2: Textual tabs, in a multi-terminal environment</figcaption>
</figure>
<p>In this example, four terminals are open in the multiple-terminal screen,
and each one has an entry on the tab list at the bottom. The third terminal
(an editor session) is currently selected, and the tab list reflects this by
highlighting the third tab.</p>
<p>Tabs in a web page are visually very similar to these two interfaces; the
above example of a login and forgot-password interface may be implemented as
per the following diagrams.</p>
<figure>
 <img src="/content/img/js-tabs-login.png" alt="Login tabs">
 <figcaption>Figure 3: Two tabs of a login page</figcaption>
</figure>
<h2>Implementation: HTML</h2>
<p>As stated above, the tab contents must be sectioned before tabbing can be
applied; a tab list must also be present to allow switching between tabs. A
simple way to break the content down is by placing each section in a
<code>DIV</code>. The correspondence between tab list item and tab content is
maintained by giving each <code>DIV</code> an <code>id</code>, which is used
as the <code>rel</code> attribute on the list item. As described in the
JavaScript section, the tab switcher will use this <code>rel</code> to
determine which tab content to switch in.</p>
<samp>
 <h3>Two-section login form, with tab code</h3>
 <pre><var>&lt;ul class="tablist" id="tablist-login"&gt;
 &lt;li rel="tab-login"&gt;Login&lt;/li&gt;
 &lt;li rel="tab-forgot"&gt;Forgot Password&lt;/li&gt;
&lt;/ul&gt;</var>
<var>&lt;div class="tab" id="tab-login"&gt;</var>
 &lt;form action="/login" method="post"&gt;
  &lt;fieldset&gt;
   &lt;legend&gt;Provide login details&lt;/legend&gt;
   &lt;label for="user"&gt;Username:&lt;/label&gt;&lt;input type="text" name="username" id="user"&gt;
   &lt;label for="pass"&gt;Password:&lt;/label&gt;&lt;input type="password" name="password" id="pass"&gt;
   &lt;input type="hidden" name="do" value="login"&gt;
   &lt;input type="submit" name="go" value="Login"&gt;
  &lt;/fieldset&gt;
 &lt;/form&gt;
<var>&lt;/div&gt;</var>
<var>&lt;div class="tab" id="tab-forgot"&gt;</var>
 &lt;form action="/login" method="post"&gt;
  &lt;fieldset&gt;
   &lt;legend&gt;Provide e-mail&lt;/legend&gt;
   &lt;label for="email"&gt;E-mail:&lt;/label&gt;&lt;input type="text" name="email" id="email"&gt;
   &lt;input type="hidden" name="do" value="forgot"&gt;
   &lt;input type="submit" name="go" value="Get Password"&gt;
  &lt;/fieldset&gt;
 &lt;/form&gt;
<var>&lt;/div&gt;</var></pre>
</samp>
<h2>Implementation: CSS</h2>
<p>Each tab in the tablist can be in one of two states: active (the currently
selected tab) or inactive. In the above example, the tab list has been coded as
an unordered list, which means that the list items must be floated next to each
other if they are to appear on the same line.</p>
<p>The tab content <code>DIV</code> is a simple matter to style: a black border
will suffice. The tab list, however, has to be positioned such that the
"active" tab will visually merge with the tab contents. The easiest way to do
this is to give the active tab and the tab content box the same background (in
this case, white), and to set a bottom border on the active tab of white. From
here, the tab list can be positioned to overlay the tab content, causing the
active tab's white border to visually override the content's black border.</p>
<p>In CSS, the implementation could be as follows.</p>
<samp>
 <h3>CSS for tab rendering</h3>
 <pre><s>/* Tab list: no bullets */</s>
<kbd>ul</kbd>.tablist {
  <kbd>list-style</kbd>: none inside;
  <kbd>margin</kbd>: <var>0</var>;
  <kbd>padding</kbd>: <var>0</var>;
}

<s>/* Tab list item: floated, pushed down one pixel */</s>
<kbd>ul</kbd>.tablist <kbd>li</kbd> {
  <kbd>display</kbd>: block;
  <kbd>float</kbd>: left;
  <kbd>background</kbd>: <var>#ddd</var>;
  <kbd>border-top</kbd>: <var>1px</var> solid <var>#ddd</var>;
  <kbd>border-bottom</kbd>: <var>1px</var> solid black;
  <kbd>position</kbd>: relative;
  <kbd>bottom</kbd>: <var>-1px</var>;
  <kbd>padding</kbd>: <var>0.5em</var>;
  <kbd>margin-right</kbd>: <var>2px</var>;
  <kbd>cursor</kbd>: pointer;
}

<s>/* Tab list item (active): white bottom border */</s>
<kbd>ul</kbd>.tablist <kbd>li</kbd>.active {
  <kbd>background</kbd>: white;
  <kbd>border-left</kbd>: <var>1px</var> solid black;
  <kbd>border-right</kbd>: <var>1px</var> solid black;
  <kbd>border-top</kbd>: <var>1px</var> solid black;
  <kbd>border-bottom</kbd>: <var>1px</var> solid white;
}

<s>/* Tab: black border */</s>
<kbd>div</kbd>.tab {
  <kbd>border</kbd>: <var>1px</var> solid black;
  <kbd>clear</kbd>: both;
  <kbd>padding</kbd>: <var>0.5em</var>;
}</pre>
</samp>
<h2>Implementation: JavaScript</h2>
<p>The most important part of the tabbing system is the active component: that
part which switches in a tab and switches out the others, when an item on the
tab list is clicked. In order to do this, a mapping must be maintained of which
tab list items are in a particular list; this map can be created at the time
the page is loaded.</p>
<p>At initialisation time, each item in a tab list is also given an
<code>onclick</code> function, to activate the switching mechanism when the
tab is clicked by the user. The mechanism is a simple loop, determining which
tab content boxes are to be switched, and hiding every tab except the one
requested.</p>
<samp>
 <h3>JavaScript tab switcher</h3>
 <pre>tabSwitcher = {
  _map: {},

  init: function()
  {
    <s>// Check each UL on the page, to see if it's a tablist</s>
    lists = document.getElementsByTagName(<var>'ul'</var>);
    for(i=<var>0</var>; i&lt;lists.length; i++)
    {
      if(lists[i].className.indexOf(<var>'tablist'</var>) &gt;= <var>0</var>)
      {
        <s>// If we find a tablist, put each item in the map</s>
	items = lists[i].getElementsByTagName(<var>'li'</var>);
	for(j=<var>0</var>; j&lt;items.length; j++)
	{
	  <s>// Map the item's REL attribute to this tablist</s>
	  tabSwitcher._map[items[j].getAttribute(<var>'rel'</var>)] = lists[i].id;

	  <s>// When the user clicks this item, run switcher</s>
	  items[j].onclick = function()
	  {
	    tabSwitcher.action(this.getAttribute(<var>'rel'</var>));
	    return <var>false</var>;
	  };
	}

	<s>// Leave this tab list in a default state of
	// first item active</s>
	tabSwitcher.action(items[<var>0</var>].getAttribute(<var>'rel'</var>));
      }
    }
  },

  action: function(target)
  {
    <s>// Fetch all the tab list items in the same list as the target</s>
    tablist = document.getElementById(tabSwitcher._map[target]);
    listitems = tablist.getElementsByTagName(<var>'li'</var>);

    for(k=<var>0</var>; k&lt;listitems.length; k++)
    {
      <s>// If this item's REL is the same as the clicked item,
      // activate the tab list item and show the content</s>
      rel = listitems[k].getAttribute(<var>'rel'</var>);
      if(rel == target)
      {
        listitems[k].className = <var>'tab_hi'</var>;
        document.getElementById(rel).style.display = <var>'block'</var>;
      }

      <s>// Otherwise, make the tab list item inactive and hide the content</s>
      else
      {
        listitems[k].className = <var>'tab'</var>;
        document.getElementById(rel).style.display = <var>'none'</var>;
      }
    }
  }
};

window.onload = tabSwitcher.init;</pre>
</samp>
<p>Putting all these code sections together provides:</p>
<script type="text/javascript">
tabMagic = {
  _map: {},

  init: function()
  {
    l = document.getElementsByTagName('ul');
    for(i=0; i<l.length; i++)
    {
      if(l[i].className.indexOf('tablist') >= 0)
      {
	t = l[i].getElementsByTagName('li');
	for(j=0; j<t.length; j++)
	{
	  tabMagic._map[t[j].getAttribute('rel')] = l[i].id;
	  t[j].onclick = function()
	  {
	    tabMagic.sw(this.getAttribute('rel'));
	    return false;
	  };
	}
	tabMagic.sw(t[0].getAttribute('rel'));
      }
    }
  },

  sw: function(tr)
  {
    tl = document.getElementsByTagName('ul');
    for(li=0; li<tl.length; li++)
    {
      if(tl[li].className.indexOf('tablist') >= 0 && tl[li].id == tabMagic._map[tr])
      {
        items = tl[li].getElementsByTagName('li');
	for(lj=0; lj<items.length; lj++)
	{
	  if(items[lj].getAttribute('rel') == tr)
	  {
	    items[lj].className = 'tab_hi';
	    document.getElementById(items[lj].getAttribute('rel')).style.display = 'block';
	  }
	  else
	  {
	    items[lj].className = 'tab';
	    document.getElementById(items[lj].getAttribute('rel')).style.display = 'none';
	  }
	}
      }
    }
  }
};

window.onload = tabMagic.init;
</script>
<figure>
 <div id="tabs-ex">
  <ul class='tablist' id='tablist-login'>
   <li rel='login'>Login</li>
   <li rel='forgot'>Forgot Password</li>
  </ul>
  <div class='tab' id='login'>
   <form action='' method='post'>
    <fieldset>
     <legend>User information</legend>
     <input type='hidden' name='action' value='user:login'>
     <label for='user' class='reqd {$BadUser}'>Username:<input type='text' name='user' id='user' value=''></label>
     <label for='pass' class='reqd {$BadPass}'>Password:<input type='password' name='pass' id='pass'></label>
     <input class='submit' type='submit' name='login' value='Login'>
    </fieldset>
   </form>
   </div>
  <div class='tab' id='forgot'>
   <form action='' method='post'>
    <fieldset>
     <legend>User information</legend>
     <input type='hidden' name='action' value='user:forgot'>
     <label for='email' class='reqd {$BadEmail}'>E-mail:<input type='text' name='email' id='email' value=''></label>
     <input class='submit' type='submit' name='forgot' value='Get Password'>
    </fieldset>
   </form>
  </div>
 </div>
 <figcaption>Figure 4: Tabbed interface example</figcaption>
</figure>
<h2>Advanced usage: Multiple tab lists</h2>
<p>Since the above JavaScript code is designed to map a tab list item to the
list within which it's contained, it's possible to place multiple tab lists
on the same page, and have each work independently; the tab switcher will
maintain the relations to the appropriate tab lists in its internal map. This
can be used for a detailed drill-down display, or any other point at which a
tab list could be nested within another tab.</p>
<p>The styling of tabs can also be enhanced, to make judicious use of rounded
tabs, colouring and the like; since the styling has been separated from the
presentational HTML, restyling the tabs is merely a matter of changing the CSS
used to define the tab styles.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2009</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">NotPDO for PHP: Wrapping MySQL to look like PDO</title>
 <link href="https://imrannazar.com/hacks/notpdo" rel="alternate" type="text/html" title="NotPDO for PHP: Wrapping MySQL to look like PDO" />
 <id>https://imrannazar.com/hacks/notpdo</id>
 <summary>It doesn&#039;t happen very often, but it does happen: you&#039;re deploying a PDO-based PHP application to a shared host, and they don&#039;t run PDO. If you can&#039;t reconfigure the server, you can always wrap MySQL to look like PDO; that&#039;s what NotPDO does.</summary>
 <category term="Quick Hacks" />
 <published>Sat, 14 Feb 2009 19:39:20 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Ever been in a situation where you need PDO-MySQL installed and running,
but you don't have it? If it's imperative for your script to run database
queries through PDO, and it's not installed on the server, there is a way to
alleviate the problem: use a wrapper that looks like PDO.</p>
<p>The following is just such a wrapper, that I wrote to get an application
running on a new host quickly. It's a hack, and functionality is missing that
would otherwise be in PDO, but it covers the basics.</p>
<samp>
 <h3>NotPDO.php: PDO lookalike wrapper for MySQL</h3>
 <pre>&lt;?php

<kbd>class</kbd> NotPDO 
{
    <kbd>private</kbd> $dbconn;

    <kbd>function</kbd> NotPDO($dsn, $user=<var>''</var>, $pass=<var>''</var>)
    {
        $dsnparts = <kbd>explode</kbd>(<var>':'</var>, $dsn);
        <kbd>switch</kbd>($dsnparts[0])
        {
            <kbd>case</kbd> <var>'mysql'</var>:
                $dsnparams = <kbd>explode</kbd>(<var>';'</var>, $dsnparts[1]);
                <kbd>foreach</kbd>($dsnparams as $dsnp)
                {
                    $dsnpv = <kbd>explode</kbd>(<var>'='</var>, $dsnp);
                    <kbd>switch</kbd>($dsnpv[0])
                    {
                        <kbd>case</kbd> <var>'host'</var>:
                            $host = $dsnpv[1];
                            <kbd>break</kbd>;
                        <kbd>case</kbd> <var>'dbname'</var>:
                            $dbname = $dsnpv[1];
                            <kbd>break</kbd>;
                    }
                }

                <kbd>if</kbd>(<kbd>isset</kbd>($host) &amp;&amp; <kbd>isset</kbd>($dbname))
                {
                    $<kbd>this</kbd>-&gt;dbconn = mysql_connect($host, $user, $pass);
                    <kbd>if</kbd>(!$<kbd>this</kbd>-&gt;dbconn)
                        <kbd>die</kbd>(<var>'NotPDO: Database connection failed.'</var>);
                    <kbd>if</kbd>(!mysql_select_db($dbname, $<kbd>this</kbd>-&gt;dbconn))
                        <kbd>die</kbd>(<var>'NotPDO: Could not select database.'</var>);
                }
                <kbd>else</kbd>
                {
                    <kbd>die</kbd>(<var>'NotPDO: Database not specified.'</var>);
                }
                <kbd>break</kbd>;

            default:
                <kbd>die</kbd>(<var>'NotPDO: Database type not supported.'</var>);
        }
    }

    <kbd>function</kbd> prepare($q)
    {
        <kbd>return</kbd> <kbd>new</kbd> NotPDOQuery($q, $<kbd>this</kbd>-&gt;dbconn);
    }

    <kbd>function</kbd> query($q)
    {
        $q = <kbd>new</kbd> NotPDOQuery($q, $<kbd>this</kbd>-&gt;dbconn);
        $q-&gt;execute();
        <kbd>return</kbd> $q;
    }
};

<kbd>class</kbd> NotPDOQuery
{
    <kbd>private</kbd> $dbconn;
    <kbd>private</kbd> $q;
    <kbd>private</kbd> $r;

    <kbd>function</kbd> NotPDOQuery($query, $dbconn)
    {
        $<kbd>this</kbd>-&gt;dbconn = $dbconn;
        $<kbd>this</kbd>-&gt;q = $query;
    }

    <kbd>function</kbd> bindParam($param, $val)
    {
        <kbd>if</kbd>(<kbd>is_numeric</kbd>($val))
        {
            $<kbd>this</kbd>-&gt;q = <kbd>str_replace</kbd>(
                              $param,
                              mysql_real_escape_string($val, $<kbd>this</kbd>-&gt;dbconn),
                              $<kbd>this</kbd>-&gt;q);
        }
        <kbd>else</kbd>
        {
            $<kbd>this</kbd>-&gt;q = <kbd>str_replace</kbd>(
                              $param,
                              <var>"'"</var>.mysql_real_escape_string($val, $<kbd>this</kbd>-&gt;dbconn).<var>"'"</var>,
                              $<kbd>this</kbd>-&gt;q);
        }
    }

    <kbd>function</kbd> execute()
    {
        $<kbd>this</kbd>-&gt;r = mysql_query($<kbd>this</kbd>-&gt;q);
        <kbd>if</kbd>($<kbd>this</kbd>-&gt;r)
            <kbd>return</kbd> <kbd>true</kbd>;
        <kbd>else</kbd>
            <kbd>return</kbd> <kbd>false</kbd>;
    }

    <kbd>function</kbd> fetch()
    {
        <kbd>return</kbd> mysql_fetch_assoc($<kbd>this</kbd>-&gt;r);
    }

    <kbd>function</kbd> fetchAll()
    {
        $arr = <kbd>array</kbd>();
        <kbd>if</kbd>(mysql_num_rows($<kbd>this</kbd>-&gt;r)) mysql_data_seek($<kbd>this</kbd>-&gt;r, 0);
        <kbd>while</kbd>($row = mysql_fetch_assoc($<kbd>this</kbd>-&gt;r)) $arr[] = $row;
        <kbd>return</kbd> $arr;
    }
};

?&gt;</pre>
</samp>
 ]]></content>
</entry>
<entry>
 <title type="html">Modified Preorder Tree Traversal</title>
 <link href="https://imrannazar.com/articles/modified-preorder-tree-traversal" rel="alternate" type="text/html" title="Modified Preorder Tree Traversal" />
 <id>https://imrannazar.com/articles/modified-preorder-tree-traversal</id>
 <summary>Exploring the MPTT algorithm, and how it can be used for hierarchical data storage. Includes algorithms for addition to and removal from the tree.</summary>
 <category term="Articles" />
 <published>Mon, 09 Feb 2009 14:53:00 +0000</published>
 <content type="text/html"><![CDATA[
      <p>The MPTT algorithm is, as the name states, a modification of pre-order tree traversal; each node of the tree has two extra values associated to it, to assist in the traversal of the tree.</p>
   <h2>Data structure</h2>
   <figure>
   <table>
    <thead>
     <tr><th>Node ID</th><th>Name</th><th>Left MPTT value</th><th>Right MPTT value</th></tr>
    </thead>
    <tbody>
     <tr><td>1</td><td>(Root)</td><td>1</td><td>16</td></tr>
     <tr><td>2</td><td>Articles</td><td>2</td><td>11</td></tr>
     <tr><td>5</td><td>Fiction</td><td>3</td><td>8</td></tr>
     <tr><td>7</td><td>Fantasy</td><td>4</td><td>5</td></tr>
     <tr><td>8</td><td>Sci-fi</td><td>6</td><td>7</td></tr>
     <tr><td>6</td><td>Reference</td><td>9</td><td>10</td></tr>
     <tr><td>3</td><td>Portfolio</td><td>12</td><td>13</td></tr>
     <tr><td>4</td><td>Contact</td><td>14</td><td>15</td></tr>
    </tbody>
   </table>
   <figcaption><code>SELECT * from Pages order by mpttLeft asc</code></figcaption>
   </figure>
   <figure class='invertable'>
    <img src='/content/img/mptt-tree.png'>
    <figcaption>Figure 1: Sample MPTT tree</figcaption>
   </figure>
   <p>Numbers are assigned such that a path can be traced around the tree, taking in every node. The path here starts at (Root), flowing down the left, around the bottom of the Fiction subtree, then up to the Reference branch of Articles, and from there to the other branches of (Root), before flowing back to (Root).</p>
   <p>Note that leaf nodes (those with no children) have Left and Right values immediately after each other; Portfolio, for example, is 12/13. Note also that the parent of a node has a smaller Left and a bigger Right; this can be used to trace up the tree finding parent nodes, until you hit a Left of 1 (meaning the root node). For example, Fantasy (4/5) has a parent of Fiction (3/8), which has a parent of Articles (2/11).</p>
   <h2>Operations</h2>
   <dl>
    <dt>Addition</dt>
    <dd>
     To add a node, simply add 2 to all the values after that node, then insert the node into place. As an example, inserting a "Horror" section under Fiction is a simple matter of:
     <ul>
      <li>Finding where to insert "Horror" (after 7)</li>
      <li>Adding 2 to every Left value past 7</li>
      <li>Adding 2 to every Right value past 7</li>
      <li>Inserting a new row, "Horror", with Left=8 and Right=9</li>
     </ul>
     At the end of this, "Fiction" would have a Left of 3 and Right of 10.
    </dd>
    <dt>Removal</dt>
    <dd>
     A very similar process is used to delete a node from the tree. For example, to delete "Fantasy":
     <ul>
      <li>Fetch the Right value of the node (in this case, 5)</li>
      <li>Subtract 2 from every Left value past 5</li>
      <li>Subtract 2 from every Right value past 5</li>
      <li>Remove the node row</li>
     </ul>
    </dd>
   </dl>
 ]]></content>
</entry>
<entry>
 <title type="html">CRC32 Calculation in 256 Bytes</title>
 <link href="https://imrannazar.com/hacks/crc32" rel="alternate" type="text/html" title="CRC32 Calculation in 256 Bytes" />
 <id>https://imrannazar.com/hacks/crc32</id>
 <summary>A quick look at a 256-byte program capable of calculating the CRC32 checksum of a file.</summary>
 <category term="Quick Hacks" />
 <published>Mon, 09 Feb 2009 14:22:44 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The following program is in <code>nasm</code> format, and assembles to a
DOS .com executable of 240 bytes.</p>
<p>The program is based on Horst Sch&auml;ffer's 784-byte CRC32 calculator,
which is part of the PBATS32 collection.</p>
<samp>
 <h3>crc32.asm: A CRC32 calculator</h3>
 <pre>[bits 16]
	org 0x0100
start:
	mov di,CMDBUF
	mov cx,0x7800
	xor ax,ax
	rep stosw

	mov di,LUTBUF
	xor cx,cx
.lutolp:
	xor dx,dx
	mov ax,cx
	mov ch,8
.lutlp:
	shr dx,1
	rcr ax,1
	jnc .xorskip
	xor dx,0xEDB8
	xor ax,0x8320
.xorskip:
	dec ch
	jnz .lutlp
	stosw
	mov ax,dx
	stosw
	inc cx
	and ch,ch
	jz .lutolp

	mov si,0x81
	mov di,CMDBUF
	mov dx,di
.getarg:
	lodsb
	cmp al,' '
	je .getarg
	jb .aend
	cmp al,','
	je .aend
	cmp al,'/'
	je .aend
	stosb
	jmp short .getarg

.aend:
	cmp dx,di
	je printhelp

	push di
	mov ax,0x3D40
	int 0x21
	jc printhelp
	mov bp,ax
	mov di,LUTBUF
	xor ax,ax
	dec ax
	cwd
.crcolp:
	push ax
	push dx
	mov si,READBUF
	mov dx,si
	mov cx,READBLEN
	mov bx,bp
	mov ah,0x3F
	int 0x21
	mov cx,ax
	pop dx
	pop ax
	jc .crcend
	jcxz .crcdone
.crclp:
	mov bx,ax
	lodsb
	xor bx,ax
	shl bx,2
	mov al,ah
	mov ah,dl
	mov dl,dh
	xor dh,dh
	xor ax,[bx+di]
	xor dx,[bx+di+2]
	loop .crclp
	cmp si,READBUF+READBLEN
	jnc .crcolp
.crcdone:
	not ax
	not dx
.crcend:
	push ax
	mov bx,bp
	mov ah,0x3e
	int 0x21
	pop bx

	pop di
	mov al,' '
	stosb
	mov cx,4
.prn:
	mov al,dh
	mov dh,dl
	mov dl,bh
	mov bh,bl
	call byteascii
	loop .prn

	mov ax,0x0a0d
	stosw
	mov al,'$'
	stosb

	mov dx,CMDBUF
	jmp short printmsg

printhelp:
	mov dx,msghelp
printmsg:
	mov ah,9
	int 0x21
	ret

byteascii:
	xor ah,ah
	div byte [divider]
	call .inner
	xchg ah,al
.inner:
	cmp al,10
	sbb al,0x69
	das
	stosb
	ret

divider:
	db 16

msghelp:
	db "Usage: CRC32 &lt;file&gt;",13,10,'$'

CMDBUF		equ 0x03C3
LUTBUF		equ 0x0468
READBUF		equ 0x0968
READBLEN	equ 0xC000</pre>
</samp>
 ]]></content>
</entry>
<entry>
 <title type="html">List of countries and dependent territories</title>
 <link href="https://imrannazar.com/hacks/countries-list" rel="alternate" type="text/html" title="List of countries and dependent territories" />
 <id>https://imrannazar.com/hacks/countries-list</id>
 <summary>If you&#039;ve ever needed to know which country is at UTC+3.5 (it&#039;s Iran), or who is responsible for administrating the Western Sahara (that&#039;s Morocco), it&#039;s all in here. List is also available in SQL, for such situations as a &#039;select your country&#039; dropdown on an e-commerce Website.</summary>
 <category term="Quick Hacks" />
 <published>Wed, 31 Dec 2008 20:36:20 +0000</published>
 <content type="text/html"><![CDATA[
   <style type="text/css">
tr.gone td { color: #888; }
tr.sub td { color: #c11; }
#content tr.sub td.country { padding-left: 2em; }
</style>
<p>Below is a table of countries, with their ISO and UN codes, assigned
top-level Internet domains and timezone relative to UTC. In all cases, there
may be gaps where the ISO or UN codes, or Internet domains, have not yet been
assigned. Dependent territories are provided as entries under the country to
which responsibility is recognised; entities which no longer exist are shown
in grey.</p>
<p>Caveats apply especially in the cases of Serbia, Montenegro and Kosovo,
where the codes may have changed since this list was produced.</p>
<p>This list is also available in SQL format, where the following fields are
defined:</p>
<ul>
 <li><strong><code>country_id</code></strong>: Sequential from 1 to 250;</li>
 <li><strong><code>name</code></strong>: Alpha characters, ASCII;</li>
 <li><strong><code>iso2</code></strong>: ISO alpha-2 code if available;</li>
 <li><strong><code>iso3</code></strong>: ISO alpha-3 code if available;</li>
 <li><strong><code>un3</code></strong>: UN number if available;</li>
 <li><strong><code>sovereign</code></strong>: Flag (0 if dependent territory);</li>
 <li><strong><code>extant</code></strong>: Flag (0 if no longer existing);</li>
 <li><strong><code>parent</code></strong>: Set to parent's <code>country_id</code> if dependent;</li>
 <li><strong><code>cctld</code></strong>: Two-character Internet domain;</li>
 <li><strong><code>time_offset</code></strong>: Number of hours from UTC.</li>
</ul>
<p><a href="http://imrannazar.com/content/files/countries.sql">http://imrannazar.com/content/files/countries.sql</a></p>
<table>
 <thead>
  <tr><th>Country</th><th>ISO alpha-2</th><th>ISO alpha-3</th><th>UN number</th><th>Internet TLD</th><th>Timezone</th></tr>
 </thead>
 <tbody>
<tr class=""><td class="country">Afghanistan</td><td>AF</td><td>AFG</td><td>004</td><td>af</td><td>+4.50</td></tr>
<tr class=""><td class="country">Albania</td><td>AL</td><td>ALB</td><td>008</td><td>al</td><td>+1</td></tr>
<tr class=""><td class="country">Algeria</td><td>DZ</td><td>DZA</td><td>012</td><td>dz</td><td>+1</td></tr>
<tr class=""><td class="country">Andorra</td><td>AD</td><td>AND</td><td>020</td><td>ad</td><td>+1</td></tr>
<tr class=""><td class="country">Angola</td><td>AO</td><td>AGO</td><td>024</td><td>ao</td><td>+1</td></tr>
<tr class=""><td class="country">Antigua and Barbuda</td><td>AG</td><td>ATG</td><td>028</td><td>ag</td><td>-4</td></tr>
<tr class=""><td class="country">Argentina</td><td>AR</td><td>ARG</td><td>032</td><td>ar</td><td>-3</td></tr>
<tr class=""><td class="country">Armenia</td><td>AM</td><td>ARM</td><td>051</td><td>am</td><td>+4</td></tr>
<tr class=""><td class="country">Australia</td><td>AU</td><td>AUS</td><td>036</td><td>au</td><td>+10</td></tr>
<tr class="sub"><td class="country">Christmas Island</td><td></td><td></td><td></td><td>cx</td><td>+7</td></tr>
<tr class="sub"><td class="country">Cocos (Keeling) Island</td><td></td><td></td><td></td><td>cc</td><td>+6.50</td></tr>
<tr class="sub"><td class="country">Heard and McDonald Islands</td><td></td><td></td><td></td><td>hm</td><td>+5</td></tr>
<tr class="sub"><td class="country">Norfolk Island</td><td>NF</td><td>NFK</td><td>574</td><td>nf</td><td>+11.50</td></tr>
<tr class=""><td class="country">Austria</td><td>AT</td><td>AUT</td><td>040</td><td>at</td><td>+1</td></tr>
<tr class=""><td class="country">Azerbaijan</td><td>AZ</td><td>AZE</td><td>031</td><td>az</td><td>+4</td></tr>
<tr class=""><td class="country">Bahamas</td><td>BS</td><td>BHS</td><td>044</td><td>bs</td><td>-5</td></tr>
<tr class=""><td class="country">Bahrain</td><td>BH</td><td>BHR</td><td>048</td><td>bh</td><td>+3</td></tr>
<tr class=""><td class="country">Bangladesh</td><td>BD</td><td>BGD</td><td>050</td><td>bd</td><td>+6</td></tr>
<tr class=""><td class="country">Barbados</td><td>BB</td><td>BRB</td><td>052</td><td>bb</td><td>-4</td></tr>
<tr class=""><td class="country">Belarus</td><td>BY</td><td>BLR</td><td>112</td><td>by</td><td>+2</td></tr>
<tr class=""><td class="country">Belgium</td><td>BE</td><td>BEL</td><td>056</td><td>be</td><td>+1</td></tr>
<tr class=""><td class="country">Belize</td><td>BZ</td><td>BLZ</td><td>084</td><td>bz</td><td>-6</td></tr>
<tr class=""><td class="country">Benin</td><td>BJ</td><td>BEN</td><td>204</td><td>bj</td><td>+1</td></tr>
<tr class=""><td class="country">Bhutan</td><td>BT</td><td>BTN</td><td>064</td><td>bt</td><td>+6</td></tr>
<tr class=""><td class="country">Bolivia</td><td>BO</td><td>BOL</td><td>068</td><td>bo</td><td>-4</td></tr>
<tr class=""><td class="country">Bosnia and Herzegovina</td><td>BA</td><td>BIH</td><td>070</td><td>ba</td><td>+1</td></tr>
<tr class=""><td class="country">Botswana</td><td>BW</td><td>BWA</td><td>072</td><td>bw</td><td>+2</td></tr>
<tr class=""><td class="country">Brazil</td><td>BR</td><td>BRA</td><td>076</td><td>br</td><td>-3</td></tr>
<tr class=""><td class="country">Brunei Darussalam</td><td>BN</td><td>BRN</td><td>096</td><td>bn</td><td>+8</td></tr>
<tr class=""><td class="country">Bulgaria</td><td>BG</td><td>BGR</td><td>100</td><td>bg</td><td>+2</td></tr>
<tr class=""><td class="country">Burkina Faso</td><td>BF</td><td>BFA</td><td>854</td><td>bf</td><td>+0</td></tr>
<tr class=""><td class="country">Burundi</td><td>BI</td><td>BDI</td><td>108</td><td>bi</td><td>+2</td></tr>
<tr class=""><td class="country">Cambodia</td><td>KH</td><td>KHM</td><td>116</td><td>kh</td><td>+7</td></tr>
<tr class=""><td class="country">Cameroon</td><td>CM</td><td>CMR</td><td>120</td><td>cm</td><td>+1</td></tr>
<tr class=""><td class="country">Canada</td><td>CA</td><td>CAN</td><td>124</td><td>ca</td><td>-5</td></tr>
<tr class=""><td class="country">Cape Verde</td><td>CV</td><td>CPV</td><td>132</td><td>cv</td><td>-1</td></tr>
<tr class=""><td class="country">Central African Republic</td><td>CF</td><td>CAF</td><td>140</td><td>cf</td><td>+1</td></tr>
<tr class=""><td class="country">Chad</td><td>TD</td><td>TCD</td><td>148</td><td>td</td><td>+1</td></tr>
<tr class=""><td class="country">Chile</td><td>CL</td><td>CHL</td><td>152</td><td>cl</td><td>-4</td></tr>
<tr class=""><td class="country">China</td><td>CN</td><td>CHN</td><td>156</td><td>cn</td><td>+8</td></tr>
<tr class="sub"><td class="country">Hong Kong</td><td>HK</td><td>HKG</td><td>344</td><td>hk</td><td>+8</td></tr>
<tr class="sub"><td class="country">Macau</td><td>MO</td><td>MAC</td><td>446</td><td>mo</td><td>+8</td></tr>
<tr class=""><td class="country">Colombia</td><td>CO</td><td>COL</td><td>170</td><td>co</td><td>-5</td></tr>
<tr class=""><td class="country">Comoros</td><td>KM</td><td>COM</td><td>174</td><td>km</td><td>+3</td></tr>
<tr class=""><td class="country">Congo, Democratic Republic of</td><td>CD</td><td>COD</td><td>180</td><td>cd</td><td>+1</td></tr>
<tr class=""><td class="country">Congo, Republic of</td><td>CG</td><td>COG</td><td>178</td><td>cg</td><td>+1</td></tr>
<tr class=""><td class="country">Costa Rica</td><td>CR</td><td>CRI</td><td>188</td><td>cr</td><td>-6</td></tr>
<tr class=""><td class="country">Cote d'Ivoire</td><td>CI</td><td>CIV</td><td>384</td><td>ci</td><td>+0</td></tr>
<tr class=""><td class="country">Croatia</td><td>HR</td><td>HRV</td><td>191</td><td>hr</td><td>+1</td></tr>
<tr class=""><td class="country">Cuba</td><td>CU</td><td>CUB</td><td>192</td><td>cu</td><td>-5</td></tr>
<tr class=""><td class="country">Cyprus</td><td>CY</td><td>CYP</td><td>196</td><td>cy</td><td>+2</td></tr>
<tr class=""><td class="country">Czech Republic</td><td>CZ</td><td>CZE</td><td>203</td><td>cz</td><td>+1</td></tr>
<tr class=""><td class="country">Denmark</td><td>DK</td><td>DNK</td><td>208</td><td>dk</td><td>+1</td></tr>
<tr class="sub"><td class="country">Faroe Islands</td><td>FO</td><td>FRO</td><td>234</td><td>fo</td><td>+0</td></tr>
<tr class="sub"><td class="country">Greenland</td><td>GL</td><td>GRL</td><td>304</td><td>gl</td><td>-3</td></tr>
<tr class=""><td class="country">Djibouti</td><td>DJ</td><td>DJI</td><td>262</td><td>dj</td><td>+3</td></tr>
<tr class=""><td class="country">Dominica</td><td>DM</td><td>DMA</td><td>212</td><td>dm</td><td>-4</td></tr>
<tr class=""><td class="country">Dominican Republic</td><td>DO</td><td>DOM</td><td>214</td><td>do</td><td>-4</td></tr>
<tr class=""><td class="country">Ecuador</td><td>EC</td><td>ECU</td><td>218</td><td>ec</td><td>-5</td></tr>
<tr class=""><td class="country">Egypt</td><td>EG</td><td>EGY</td><td>818</td><td>eg</td><td>+2</td></tr>
<tr class=""><td class="country">El Salvador</td><td>SV</td><td>SLV</td><td>222</td><td>sv</td><td>-6</td></tr>
<tr class=""><td class="country">Equatorial Guinea</td><td>GQ</td><td>GNQ</td><td>226</td><td>gq</td><td>+1</td></tr>
<tr class=""><td class="country">Eritrea</td><td>ER</td><td>ERI</td><td>232</td><td>er</td><td>+3</td></tr>
<tr class=""><td class="country">Estonia</td><td>EE</td><td>EST</td><td>233</td><td>ee</td><td>+2</td></tr>
<tr class=""><td class="country">Ethiopia</td><td>ET</td><td>ETH</td><td>230</td><td>et</td><td>+3</td></tr>
<tr class=""><td class="country">Fiji</td><td>FJ</td><td>FJI</td><td>242</td><td>fj</td><td>+12</td></tr>
<tr class=""><td class="country">Finland</td><td>FI</td><td>FIN</td><td>246</td><td>fi</td><td>+2</td></tr>
<tr class="sub"><td class="country">Aland</td><td>AX</td><td>ALA</td><td>248</td><td></td><td>+2</td></tr>
<tr class=""><td class="country">France</td><td>FR</td><td>FRA</td><td>250</td><td>fr</td><td>+1</td></tr>
<tr class="sub"><td class="country">French Guiana</td><td>GF</td><td>GUF</td><td>254</td><td>gf</td><td>-3</td></tr>
<tr class="sub"><td class="country">French Polynesia</td><td>PF</td><td>PYF</td><td>258</td><td>pf</td><td>-10</td></tr>
<tr class="sub"><td class="country">French Southern Territories</td><td></td><td></td><td></td><td>tf</td><td>+5</td></tr>
<tr class="sub"><td class="country">Guadeloupe</td><td>GP</td><td>GLP</td><td>312</td><td>gp</td><td>-4</td></tr>
<tr class="sub"><td class="country">Martinique</td><td>MQ</td><td>MTQ</td><td>474</td><td>mq</td><td>-4</td></tr>
<tr class="sub"><td class="country">Mayotte</td><td>YT</td><td>MYT</td><td>175</td><td>yt</td><td>+3</td></tr>
<tr class="sub"><td class="country">New Caledonia</td><td>NC</td><td>NCL</td><td>540</td><td>nc</td><td>+11</td></tr>
<tr class="sub"><td class="country">Reunion</td><td>RE</td><td>REU</td><td>638</td><td>re</td><td>+4</td></tr>
<tr class="sub"><td class="country">Saint Pierre and Miquelon</td><td>PM</td><td>SPM</td><td>666</td><td>pm</td><td>+0</td></tr>
<tr class="sub"><td class="country">Wallis and Futuna Islands</td><td>WF</td><td>WLF</td><td>876</td><td>wf</td><td>+12</td></tr>
<tr class=""><td class="country">Gabon</td><td>GA</td><td>GAB</td><td>266</td><td>ga</td><td>+1</td></tr>
<tr class=""><td class="country">Gambia</td><td>GM</td><td>GMB</td><td>270</td><td>gm</td><td>+0</td></tr>
<tr class=""><td class="country">Georgia</td><td>GE</td><td>GEO</td><td>268</td><td>ge</td><td>+4</td></tr>
<tr class=""><td class="country">Germany</td><td>DE</td><td>DEU</td><td>276</td><td>de</td><td>+1</td></tr>
<tr class=""><td class="country">Ghana</td><td>GH</td><td>GHA</td><td>288</td><td>gh</td><td>+0</td></tr>
<tr class=""><td class="country">Greece</td><td>GR</td><td>GRC</td><td>300</td><td>gr</td><td>+2</td></tr>
<tr class=""><td class="country">Grenada</td><td>GD</td><td>GRD</td><td>308</td><td>gd</td><td>-4</td></tr>
<tr class=""><td class="country">Guatemala</td><td>GT</td><td>GTM</td><td>320</td><td>gt</td><td>-6</td></tr>
<tr class=""><td class="country">Guinea</td><td>GN</td><td>GIN</td><td>324</td><td>gn</td><td>+0</td></tr>
<tr class=""><td class="country">Guinea-Bissau</td><td>GW</td><td>GNB</td><td>624</td><td>gw</td><td>+0</td></tr>
<tr class=""><td class="country">Guyana</td><td>GY</td><td>GUY</td><td>328</td><td>gy</td><td>-4</td></tr>
<tr class=""><td class="country">Haiti</td><td>HT</td><td>HTI</td><td>332</td><td>ht</td><td>-5</td></tr>
<tr class=""><td class="country">Honduras</td><td>HN</td><td>HND</td><td>340</td><td>hn</td><td>-6</td></tr>
<tr class=""><td class="country">Hungary</td><td>HU</td><td>HUN</td><td>348</td><td>hu</td><td>+1</td></tr>
<tr class=""><td class="country">Iceland</td><td>IS</td><td>ISL</td><td>352</td><td>is</td><td>+0</td></tr>
<tr class=""><td class="country">India</td><td>IN</td><td>IND</td><td>356</td><td>in</td><td>+5.50</td></tr>
<tr class=""><td class="country">Indonesia</td><td>ID</td><td>IDN</td><td>360</td><td>id</td><td>+7</td></tr>
<tr class=""><td class="country">Iran</td><td>IR</td><td>IRN</td><td>364</td><td>ir</td><td>+3.50</td></tr>
<tr class=""><td class="country">Iraq</td><td>IQ</td><td>IRQ</td><td>368</td><td>iq</td><td>+3</td></tr>
<tr class=""><td class="country">Ireland</td><td>IE</td><td>IRL</td><td>372</td><td>ie</td><td>+0</td></tr>
<tr class=""><td class="country">Israel</td><td>IL</td><td>ISR</td><td>376</td><td>il</td><td>+2</td></tr>
<tr class=""><td class="country">Italy</td><td>IT</td><td>ITA</td><td>380</td><td>it</td><td>+1</td></tr>
<tr class=""><td class="country">Jamaica</td><td>JM</td><td>JAM</td><td>388</td><td>jm</td><td>-5</td></tr>
<tr class=""><td class="country">Japan</td><td>JP</td><td>JPN</td><td>392</td><td>jp</td><td>+9</td></tr>
<tr class=""><td class="country">Jordan</td><td>JO</td><td>JOR</td><td>400</td><td>jo</td><td>+0</td></tr>
<tr class=""><td class="country">Kazakhstan</td><td>KZ</td><td>KAZ</td><td>398</td><td>kz</td><td>+6</td></tr>
<tr class=""><td class="country">Kenya</td><td>KE</td><td>KEN</td><td>404</td><td>ke</td><td>+3</td></tr>
<tr class=""><td class="country">Kiribati</td><td>KI</td><td>KIR</td><td>296</td><td>ki</td><td>+12</td></tr>
<tr class=""><td class="country">Korea, North</td><td>KP</td><td>PRK</td><td>408</td><td>kp</td><td>+9</td></tr>
<tr class=""><td class="country">Korea, South</td><td>KR</td><td>KOR</td><td>410</td><td>kr</td><td>+9</td></tr>
<tr class=""><td class="country">Kosovo</td><td></td><td></td><td></td><td></td><td>+1</td></tr>
<tr class=""><td class="country">Kuwait</td><td>KW</td><td>KWT</td><td>414</td><td>kw</td><td>+3</td></tr>
<tr class=""><td class="country">Kyrgyzstan</td><td>KG</td><td>KGZ</td><td>417</td><td>kg</td><td>+6</td></tr>
<tr class=""><td class="country">Laos</td><td>LA</td><td>LAO</td><td>418</td><td>la</td><td>+7</td></tr>
<tr class=""><td class="country">Latvia</td><td>LV</td><td>LVA</td><td>428</td><td>lv</td><td>+2</td></tr>
<tr class=""><td class="country">Lebanon</td><td>LB</td><td>LBN</td><td>422</td><td>lb</td><td>+0</td></tr>
<tr class=""><td class="country">Lesotho</td><td>LS</td><td>LSO</td><td>426</td><td>ls</td><td>+2</td></tr>
<tr class=""><td class="country">Liberia</td><td>LR</td><td>LBR</td><td>430</td><td>lr</td><td>+0</td></tr>
<tr class=""><td class="country">Libya</td><td>LY</td><td>LBY</td><td>434</td><td>ly</td><td>+2</td></tr>
<tr class=""><td class="country">Liechtenstein</td><td>LI</td><td>LIE</td><td>438</td><td>li</td><td>+1</td></tr>
<tr class=""><td class="country">Lithuania</td><td>LT</td><td>LTU</td><td>440</td><td>lt</td><td>+2</td></tr>
<tr class=""><td class="country">Luxembourg</td><td>LU</td><td>LUX</td><td>442</td><td>lu</td><td>+1</td></tr>
<tr class=""><td class="country">Macedonia</td><td>MK</td><td>MKD</td><td>807</td><td>mk</td><td>+1</td></tr>
<tr class=""><td class="country">Madagascar</td><td>MG</td><td>MDG</td><td>450</td><td>mg</td><td>+3</td></tr>
<tr class=""><td class="country">Malawi</td><td>MW</td><td>MWI</td><td>454</td><td>mw</td><td>+2</td></tr>
<tr class=""><td class="country">Malaysia</td><td>MY</td><td>MYS</td><td>458</td><td>my</td><td>+8</td></tr>
<tr class=""><td class="country">Maldives</td><td>MV</td><td>MDV</td><td>462</td><td>mv</td><td>+5</td></tr>
<tr class=""><td class="country">Mali</td><td>ML</td><td>MLI</td><td>466</td><td>ml</td><td>+0</td></tr>
<tr class=""><td class="country">Malta</td><td>MT</td><td>MLT</td><td>470</td><td>mt</td><td>+1</td></tr>
<tr class=""><td class="country">Marshall Islands</td><td>MH</td><td>MHL</td><td>584</td><td>mh</td><td>+12</td></tr>
<tr class=""><td class="country">Mauritania</td><td>MR</td><td>MRT</td><td>478</td><td>mr</td><td>+0</td></tr>
<tr class=""><td class="country">Mauritius</td><td>MU</td><td>MUS</td><td>480</td><td>mu</td><td>+4</td></tr>
<tr class=""><td class="country">Mexico</td><td>MX</td><td>MEX</td><td>484</td><td>mx</td><td>-6</td></tr>
<tr class=""><td class="country">Micronesia</td><td>FM</td><td>FSM</td><td>583</td><td>fm</td><td>+10</td></tr>
<tr class=""><td class="country">Moldova</td><td>MD</td><td>MDA</td><td>498</td><td>md</td><td>+2</td></tr>
<tr class=""><td class="country">Monaco</td><td>MC</td><td>MCO</td><td>492</td><td>mc</td><td>+1</td></tr>
<tr class=""><td class="country">Mongolia</td><td>MN</td><td>MNG</td><td>496</td><td>mn</td><td>+8</td></tr>
<tr class=""><td class="country">Montenegro</td><td></td><td></td><td></td><td>me</td><td>+1</td></tr>
<tr class=""><td class="country">Morocco</td><td>MA</td><td>MAR</td><td>504</td><td>ma</td><td>+0</td></tr>
<tr class="sub"><td class="country">Western Sahara</td><td>EH</td><td>ESH</td><td>732</td><td>eh</td><td>+0</td></tr>
<tr class=""><td class="country">Mozambique</td><td>MZ</td><td>MOZ</td><td>508</td><td>mz</td><td>+2</td></tr>
<tr class=""><td class="country">Myanmar</td><td>MM</td><td>MMR</td><td>104</td><td>mm</td><td>+6.50</td></tr>
<tr class=""><td class="country">Namibia</td><td>NA</td><td>NAM</td><td>516</td><td>na</td><td>+2</td></tr>
<tr class=""><td class="country">Nauru</td><td>NR</td><td>NRU</td><td>520</td><td>nr</td><td>+12</td></tr>
<tr class=""><td class="country">Nepal</td><td>NP</td><td>NPL</td><td>524</td><td>np</td><td>+5.75</td></tr>
<tr class=""><td class="country">Netherlands</td><td>NL</td><td>NLD</td><td>528</td><td>nl</td><td>+1</td></tr>
<tr class="sub"><td class="country">Aruba</td><td>AW</td><td>ABW</td><td>533</td><td>aw</td><td>-4</td></tr>
<tr class="sub"><td class="country">Netherlands Antilles</td><td>AN</td><td>ANT</td><td>530</td><td>an</td><td>-4</td></tr>
<tr class=""><td class="country">New Zealand</td><td>NZ</td><td>NZL</td><td>554</td><td>nz</td><td>+12</td></tr>
<tr class="sub"><td class="country">Cook Islands</td><td>CK</td><td>COK</td><td>184</td><td>ck</td><td>-10</td></tr>
<tr class="sub"><td class="country">Niue</td><td>NU</td><td>NIU</td><td>570</td><td>nu</td><td>-11</td></tr>
<tr class="sub"><td class="country">Tokelau</td><td></td><td></td><td></td><td>tk</td><td>-10</td></tr>
<tr class=""><td class="country">Nicaragua</td><td>NI</td><td>NIC</td><td>558</td><td>ni</td><td>-6</td></tr>
<tr class=""><td class="country">Niger</td><td>NE</td><td>NER</td><td>562</td><td>ne</td><td>+1</td></tr>
<tr class=""><td class="country">Nigeria</td><td>NG</td><td>NGA</td><td>566</td><td>ng</td><td>+1</td></tr>
<tr class=""><td class="country">Norway</td><td>NO</td><td>NOR</td><td>578</td><td>no</td><td>+1</td></tr>
<tr class="sub"><td class="country">Bouvet Island</td><td></td><td></td><td></td><td>bv</td><td>+1</td></tr>
<tr class="sub"><td class="country">Svalbard and Jan Mayen Islands</td><td>SJ</td><td>SJM</td><td>744</td><td>sj</td><td>+1</td></tr>
<tr class=""><td class="country">Oman</td><td>OM</td><td>OMN</td><td>512</td><td>om</td><td>+4</td></tr>
<tr class=""><td class="country">Pakistan</td><td>PK</td><td>PAK</td><td>586</td><td>pk</td><td>+5</td></tr>
<tr class=""><td class="country">Palau</td><td>PW</td><td>PLW</td><td>585</td><td>pw</td><td>+9</td></tr>
<tr class=""><td class="country">Palestinian Territory, Occupied</td><td>PS</td><td>PSE</td><td>275</td><td>ps</td><td>+0</td></tr>
<tr class=""><td class="country">Panama</td><td>PA</td><td>PAN</td><td>591</td><td>pa</td><td>-5</td></tr>
<tr class=""><td class="country">Papua New Guinea</td><td>PG</td><td>PNG</td><td>598</td><td>pg</td><td>+10</td></tr>
<tr class=""><td class="country">Paraguay</td><td>PY</td><td>PRY</td><td>600</td><td>py</td><td>-4</td></tr>
<tr class=""><td class="country">Peru</td><td>PE</td><td>PER</td><td>604</td><td>pe</td><td>-5</td></tr>
<tr class=""><td class="country">Philippines</td><td>PH</td><td>PHL</td><td>608</td><td>ph</td><td>+8</td></tr>
<tr class=""><td class="country">Poland</td><td>PL</td><td>POL</td><td>616</td><td>pl</td><td>+1</td></tr>
<tr class=""><td class="country">Portugal</td><td>PT</td><td>PRT</td><td>620</td><td>pt</td><td>+0</td></tr>
<tr class=""><td class="country">Qatar</td><td>QA</td><td>QAT</td><td>634</td><td>qa</td><td>+3</td></tr>
<tr class=""><td class="country">Romania</td><td>RO</td><td>ROU</td><td>642</td><td>ro</td><td>+2</td></tr>
<tr class=""><td class="country">Russia</td><td>RU</td><td>RUS</td><td>643</td><td>ru</td><td>+3</td></tr>
<tr class=""><td class="country">Rwanda</td><td>RW</td><td>RWA</td><td>646</td><td>rw</td><td>+2</td></tr>
<tr class=""><td class="country">Saint Kitts and Nevis</td><td>KN</td><td>KNA</td><td>659</td><td>kn</td><td>-4</td></tr>
<tr class=""><td class="country">Saint Lucia</td><td>LC</td><td>LCA</td><td>662</td><td>lc</td><td>-4</td></tr>
<tr class=""><td class="country">Saint Vincent and the Grenadines</td><td>VC</td><td>VCT</td><td>670</td><td>vc</td><td>-4</td></tr>
<tr class=""><td class="country">Samoa</td><td>WS</td><td>WSM</td><td>882</td><td>ws</td><td>-11</td></tr>
<tr class=""><td class="country">San Marino</td><td>SM</td><td>SMR</td><td>674</td><td>sm</td><td>+1</td></tr>
<tr class=""><td class="country">Sao Tome and Principe</td><td>ST</td><td>STP</td><td>678</td><td>st</td><td>+0</td></tr>
<tr class=""><td class="country">Saudi Arabia</td><td>SA</td><td>SAU</td><td>682</td><td>sa</td><td>+3</td></tr>
<tr class=""><td class="country">Senegal</td><td>SN</td><td>SEN</td><td>686</td><td>sn</td><td>+0</td></tr>
<tr class=""><td class="country">Serbia</td><td>CS</td><td>SCG</td><td>891</td><td>rs</td><td>+1</td></tr>
<tr class=""><td class="country">Seychelles</td><td>SC</td><td>SYC</td><td>690</td><td>sc</td><td>+4</td></tr>
<tr class=""><td class="country">Sierra Leone</td><td>SL</td><td>SLE</td><td>694</td><td>sl</td><td>+0</td></tr>
<tr class=""><td class="country">Singapore</td><td>SG</td><td>SGP</td><td>702</td><td>sg</td><td>+8</td></tr>
<tr class=""><td class="country">Slovakia</td><td>SK</td><td>SVK</td><td>703</td><td>sk</td><td>+1</td></tr>
<tr class=""><td class="country">Slovenia</td><td>SI</td><td>SVN</td><td>705</td><td>si</td><td>+1</td></tr>
<tr class=""><td class="country">Solomon Islands</td><td>SB</td><td>SLB</td><td>090</td><td>sb</td><td>+11</td></tr>
<tr class=""><td class="country">Somalia</td><td>SO</td><td>SOM</td><td>706</td><td>so</td><td>+3</td></tr>
<tr class=""><td class="country">South Africa</td><td>ZA</td><td>ZAF</td><td>710</td><td>za</td><td>+2</td></tr>
<tr class=""><td class="country">Spain</td><td>ES</td><td>ESP</td><td>724</td><td>es</td><td>+1</td></tr>
<tr class=""><td class="country">Sri Lanka</td><td>LK</td><td>LKA</td><td>144</td><td>lk</td><td>+5.50</td></tr>
<tr class=""><td class="country">Sudan</td><td>SD</td><td>SDN</td><td>736</td><td>sd</td><td>+3</td></tr>
<tr class=""><td class="country">Suriname</td><td>SR</td><td>SUR</td><td>740</td><td>sr</td><td>+0</td></tr>
<tr class=""><td class="country">Swaziland</td><td>SZ</td><td>SWZ</td><td>748</td><td>sz</td><td>+2</td></tr>
<tr class=""><td class="country">Sweden</td><td>SE</td><td>SWE</td><td>752</td><td>se</td><td>+1</td></tr>
<tr class=""><td class="country">Switzerland</td><td>CH</td><td>CHE</td><td>756</td><td>ch</td><td>+1</td></tr>
<tr class=""><td class="country">Syria</td><td>SY</td><td>SYR</td><td>760</td><td>sy</td><td>+0</td></tr>
<tr class=""><td class="country">Taiwan</td><td>TW</td><td>TWN</td><td>158</td><td>tw</td><td>+8</td></tr>
<tr class=""><td class="country">Tajikistan</td><td>TJ</td><td>TJK</td><td>762</td><td>tj</td><td>+5</td></tr>
<tr class=""><td class="country">Tanzania</td><td>TZ</td><td>TZA</td><td>834</td><td>tz</td><td>+3</td></tr>
<tr class=""><td class="country">Thailand</td><td>TH</td><td>THA</td><td>764</td><td>th</td><td>+7</td></tr>
<tr class=""><td class="country">Timor-Leste</td><td>TL</td><td>TLS</td><td>626</td><td>tp</td><td>+9</td></tr>
<tr class=""><td class="country">Togo</td><td>TG</td><td>TGO</td><td>768</td><td>tg</td><td>+0</td></tr>
<tr class=""><td class="country">Tonga</td><td>TO</td><td>TON</td><td>776</td><td>to</td><td>+13</td></tr>
<tr class=""><td class="country">Trinidad and Tobago</td><td>TT</td><td>TTO</td><td>780</td><td>tt</td><td>-4</td></tr>
<tr class=""><td class="country">Tunisia</td><td>TN</td><td>TUN</td><td>788</td><td>tn</td><td>+1</td></tr>
<tr class=""><td class="country">Turkey</td><td>TR</td><td>TUR</td><td>792</td><td>tr</td><td>+2</td></tr>
<tr class=""><td class="country">Turkmenistan</td><td>TM</td><td>TKM</td><td>795</td><td>tm</td><td>+5</td></tr>
<tr class=""><td class="country">Tuvalu</td><td>TV</td><td>TUV</td><td>798</td><td>tv</td><td>+12</td></tr>
<tr class="gone"><td class="country">USSR</td><td>SU</td><td>SUN</td><td>810</td><td>su</td><td>+0</td></tr>
<tr class=""><td class="country">Uganda</td><td>UG</td><td>UGA</td><td>800</td><td>ug</td><td>+3</td></tr>
<tr class=""><td class="country">Ukraine</td><td>UA</td><td>UKR</td><td>804</td><td>ua</td><td>+2</td></tr>
<tr class=""><td class="country">United Arab Emirates</td><td>AE</td><td>ARE</td><td>784</td><td>ae</td><td>+4</td></tr>
<tr class=""><td class="country">United Kingdom</td><td>GB</td><td>GBR</td><td>826</td><td>uk</td><td>+0</td></tr>
<tr class="sub"><td class="country">Anguilla</td><td>AI</td><td>AIA</td><td>660</td><td>ai</td><td>-4</td></tr>
<tr class="sub"><td class="country">Ascension Island</td><td></td><td></td><td></td><td>ac</td><td>+0</td></tr>
<tr class="sub"><td class="country">Bermuda</td><td>BM</td><td>BMU</td><td>060</td><td>bm</td><td>-4</td></tr>
<tr class="sub"><td class="country">British Indian Ocean Territory</td><td></td><td></td><td></td><td>io</td><td>+6</td></tr>
<tr class="sub"><td class="country">British Virgin Islands</td><td>IO</td><td>VGB</td><td>092</td><td>vg</td><td>-4</td></tr>
<tr class="sub"><td class="country">Cayman Islands</td><td>KY</td><td>CYM</td><td>136</td><td>ky</td><td>-5</td></tr>
<tr class="sub"><td class="country">Falkland Islands (Malvinas)</td><td>FK</td><td>FLK</td><td>238</td><td>fk</td><td>-4</td></tr>
<tr class="sub"><td class="country">Gibraltar</td><td>GI</td><td>GIB</td><td>292</td><td>gi</td><td>+1</td></tr>
<tr class="sub"><td class="country">Guernsey</td><td>GG</td><td>GGY</td><td>831</td><td>gg</td><td>+0</td></tr>
<tr class="sub"><td class="country">Isle of Man</td><td>IM</td><td>IMN</td><td>833</td><td>im</td><td>+0</td></tr>
<tr class="sub"><td class="country">Jersey</td><td>JE</td><td>JEY</td><td>832</td><td>je</td><td>+0</td></tr>
<tr class="sub"><td class="country">Montserrat</td><td>MS</td><td>MSR</td><td>500</td><td>ms</td><td>-4</td></tr>
<tr class="sub"><td class="country">Pitcairn Island</td><td>PN</td><td>PCN</td><td>612</td><td>pn</td><td>-8</td></tr>
<tr class="sub"><td class="country">Saint Helena</td><td>SH</td><td>SHN</td><td>654</td><td>sh</td><td>+0</td></tr>
<tr class="sub"><td class="country">South Georgia and the South Sandwich Islands</td><td></td><td></td><td></td><td>gs</td><td>-2</td></tr>
<tr class="sub"><td class="country">Turks and Caicos Islands</td><td>TC</td><td>TCA</td><td>796</td><td>tc</td><td>-5</td></tr>
<tr class=""><td class="country">United States of America</td><td>US</td><td>USA</td><td>840</td><td>us</td><td>-5</td></tr>
<tr class="sub"><td class="country">American Samoa</td><td>AS</td><td>ASM</td><td>016</td><td>as</td><td>-11</td></tr>
<tr class="sub"><td class="country">Guam</td><td>GU</td><td>GUM</td><td>316</td><td>gu</td><td>+10</td></tr>
<tr class="sub"><td class="country">Northern Mariana Islands</td><td>MP</td><td>MNP</td><td>580</td><td>mp</td><td>+10</td></tr>
<tr class="sub"><td class="country">Puerto Rico</td><td>PR</td><td>PRI</td><td>630</td><td>pr</td><td>-4</td></tr>
<tr class="sub"><td class="country">US Minor Outlying Islands</td><td></td><td></td><td></td><td>um</td><td>-11</td></tr>
<tr class="sub"><td class="country">United States Virgin Islands</td><td>VI</td><td>VIR</td><td>850</td><td>vi</td><td>-4</td></tr>
<tr class=""><td class="country">Uruguay</td><td>UY</td><td>URY</td><td>858</td><td>uy</td><td>-3</td></tr>
<tr class=""><td class="country">Uzbekistan</td><td>UZ</td><td>UZB</td><td>860</td><td>uz</td><td>+5</td></tr>
<tr class=""><td class="country">Vanuatu</td><td>VU</td><td>VUT</td><td>548</td><td>vu</td><td>+11</td></tr>
<tr class=""><td class="country">Vatican City State (Holy See)</td><td>VA</td><td>VAT</td><td>336</td><td>va</td><td>+1</td></tr>
<tr class=""><td class="country">Venezuela</td><td>VE</td><td>VEN</td><td>862</td><td>ve</td><td>-4.50</td></tr>
<tr class=""><td class="country">Vietnam</td><td>VN</td><td>VNM</td><td>704</td><td>vn</td><td>+7</td></tr>
<tr class=""><td class="country">Yemen</td><td>YE</td><td>YEM</td><td>887</td><td>ye</td><td>+3</td></tr>
<tr class="gone"><td class="country">Yugoslavia</td><td>YU</td><td>YUG</td><td>890</td><td>yu</td><td>+0</td></tr>
<tr class=""><td class="country">Zambia</td><td>ZM</td><td>ZMB</td><td>894</td><td>zm</td><td>+2</td></tr>
<tr class=""><td class="country">Zimbabwe</td><td>ZW</td><td>ZWE</td><td>716</td><td>zw</td><td>+2</td></tr>
 </tbody>
</table>
 ]]></content>
</entry>
<entry>
 <title type="html">Asynchronous JavaScript and JSON</title>
 <link href="https://imrannazar.com/articles/asynchronous-js-and-json" rel="alternate" type="text/html" title="Asynchronous JavaScript and JSON" />
 <id>https://imrannazar.com/articles/asynchronous-js-and-json</id>
 <summary>The most common problem that people encounter when using AJAX is that they can&#039;t update more than one region of a Web page at the same time, since the request only comes back to fill one region. Using JSON, it&#039;s possible to update multiple regions at once, and it&#039;s even possible to run inline JavaScript in the AJAX response, automatically. The magic behind it is explained here.</summary>
 <category term="Articles" />
 <published>Tue, 30 Dec 2008 18:59:08 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One of the most common uses of asynchronous JavaScript in web development
is live page updates: loading new content for a portion of a page, without
reloading the page in full. This is made very simple by the thousands of
JavaScript examples available on the Web, but there is a deficiency inherent
in this methodology.</p>
<p>If you need to update more than one portion of a page at the same time,
the traditional asynchronous request can cause some pain. Since the
methodology only allows for the update of one portion, multiple requests have
to be generated; each of these requests will have a load time, involving
processing and transfer. The end result is that the application works less
efficiently than otherwise may be possible.</p>
<p>If instead, it were possible to retrieve all the updates in one request,
that would allow for a quicker and more responsive application. This can be
done relatively simply, by taking advantage of JavaScript Object Notation.</p>
<h2>JSON encoding</h2>
<p>By way of example, let's take a football results website that wishes to
display scores in more-or-less real time. By the traditional method of
asynchronous requests, this could be done one of two ways:</p>
<ul>
 <li>Requesting a full results update: By refreshing the results container in
 full, more transfer load is generated, especially if the results have not
 changed between requests.</li>
 <li>Requesting updates for each game: Since the client cannot know which
 games have had changed results, every game must be updated. This generates
 even more transfer and processing load than the first option.</li>
</ul>
<p>A good way to alleviate this problem would be to send only the games which
have changed score, in some easy-to-transfer encoding. JSON provides that
encoding, through a few simple rules:</p>
<ul>
 <li>A <strong>value</strong> can be a number, string, <code>true</code>,
 <code>false</code>, <code>null</code>, or one of the following two types.</li>
 <li>An <strong>array</strong> is a series of values, indexed sequentially
 from zero; values can be of any type, including another array.</li>
 <li>An <strong>object</strong> is a set of name/value pairs, where the name
 is a string and the value can be any type, including another object.</li>
</ul>
<p>If the current list of football results is as follows:</p>
<samp>
 <h3>HTML for multiple-score results page</h3>
 <pre><s>&lt;ul&gt;</s>
 <s>&lt;li&gt;</s>Manchester United: <s>&lt;strong</s> id=<var>"MAN"&gt;</var>2<s>&lt;/strong&gt;</s> - <s>&lt;strong</s> id=<var>"AST"&gt;</var>3<s>&lt;/strong&gt;</s> :Aston Villa<s>&lt;/li&gt;</s>
 <s>&lt;li&gt;</s>Arsenal: <s>&lt;strong</s> id=<var>"ARS"&gt;</var>1<s>&lt;/strong&gt;</s> - <s>&lt;strong</s> id=<var>"EVE"&gt;</var>1<s>&lt;/strong&gt;</s> :Everton<s>&lt;/li&gt;</s>
<s>&lt;/ul&gt;</s></pre>
</samp>
<p>A simplistic method of transferring some updates for the football results
may, using JSON, generate the following response:</p>
<samp>
 <h3>JSON-encoded multiple-score update</h3>
 <pre>{<var>"MAN"</var>:<var>3</var>, <var>"EVE"</var>:<var>2</var>}</pre>
</samp>
<p>As can be seen in the above response, the value for <code>MAN</code> is now
3, and the value for <code>EVE</code> is 2. These name/value pairs can be used
to update the appropriate elements: for each pair in the response, update the
element whose <code>id</code> is the name of the pair, with the new value.</p>
<h2>Handling JSON responses</h2>
<p>The name "JavaScript Object Notation" infers some native ability of
JavaScript to understand it; and indeed, it's possible for a script to simply
evaluate the JSON response and refer to its contents as if it were a normal
variable. A script to update the page contents in the manner described above
may look similar to this:</p>
<samp>
 <h3>Decoding and performing a multiple-score update</h3>
 <pre>updateScores = <kbd>function</kbd>(response)
{
    r = <kbd>eval</kbd>(<var>'('</var> + response + <var>')'</var>);
    <kbd>for</kbd> (k <kbd>in</kbd> r)
        <kbd>document</kbd>.getElementById(k).innerHTML = r[k];
};</pre>
</samp>
<p>If this function is used as the response handler by the AJAX script, it
will be able to parse the JSON-encoded strings returned from the server. One
of the advantages of using JSON is the ability to send other things than a
plain response; for example, an inline script could be sent with the update:</p>
<samp>
 <h3>JSON-encoded update with inline JS</h3>
 <pre>{<var>"MAN"</var>:<var>3</var>, <var>"EVE"</var>:<var>2</var>, <var>"script"</var>:<var>"alert('There has been an update.');"</var>}</pre>
</samp>
<p>A simple modification to the response handler will suffice to be able to
use this new inline script:</p>
<samp>
 <h3>Decoding a JSON update with a script</h3>
 <pre>updateScores = <kbd>function</kbd>(response)
{
    r = <kbd>eval</kbd>(<var>'('</var> + response + <var>')'</var>);
    <kbd>for</kbd> (k <kbd>in</kbd> r)
    {
        <kbd>if</kbd>(k == <var>'script'</var>)
	    <kbd>eval</kbd>(r[k]);
	<kbd>else</kbd>
            <kbd>document</kbd>.getElementById(k).innerHTML = r[k];
    }
};</pre>
</samp>
<p>There are a couple of caveats involved with using this methodology:</p>
<dl>
 <dt>Quoting:</dt>
 <dd>The JSON standard dictates that strings must be enclosed in double-quotes;
 this means that any double-quotes in the string contents have to be escaped if
 JavaScript is to understand them. This should automatically be handled by the
 server script's JSON encoding mechanism, but it's something that the encoder
 may trip up on.</dd>
 <dt>Security:</dt>
 <dd>Many developers refuse to conscience the use of <code>eval</code> in
 JavaScript, since it's possible for arbitrary code to be executed simply by
 returning desired code instead of the JSON response. Some precautions have
 been taken by the response handler I've set out above, but the server should
 also be employed to ensure that the requesting session is valid.</dd>
</dl>
<p>If these issues are kept in mind, JSON-encoded AJAX responses are a very
useful tool for live Website updates, and can be built upon to generate highly
efficient and responsive tools.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Using Pointers in C#</title>
 <link href="https://imrannazar.com/articles/csharp-pointers" rel="alternate" type="text/html" title="Using Pointers in C#" />
 <id>https://imrannazar.com/articles/csharp-pointers</id>
 <summary>The current crop of programming languages tend to frown upon the use of pointers, deeming them to be unsafe for everyday work; indeed, many languages ban their use altogether. C# is different: it is possible for a C# program to delve into pointers, but there are caveats. An example is given in this article, using a graphical bitmap effect driven by pointer arithmetic.</summary>
 <category term="Articles" />
 <published>Sat, 01 Nov 2008 01:30:19 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Pointers are often used in lower-level languages, such as C, as an efficient
way to access and perform operations on memory buffers. In C, as with many other
languages which allow their use, a pointer is simply a variable with a value:
that value is the address of a region of memory, and the memory can be accessed
by <em>dereferencing</em> the pointer.</p>
<p>The current generation of languages have generally eschewed pointers, and
most big thinkers in programming discourage their use. As <em>The C Programming
Language</em> states:</p>
<blockquote>
Pointers have been lumped with <code>goto</code> statement as a marvelous way
to create impossible-to-understand programs. ... With discipline, however,
pointers can be used to achieve clarity and simplicity.
</blockquote>
<p>It's for this reason that the team behind the development of C# ran against
the trend of removal for pointer syntax, and included pointers in the language.
<h2>Pointers and <code>unsafe</code> blocks</h2>
<p>C# is one of the languages in the .NET family, and as such is run under the
Common Language Runtime (CLR). It's the runtime that takes care of memory
operations and lower-level functionality on the program's behalf, so that the
program doesn't normally have to worry about pointers or memory buffers.</p>
<p>The language does, however, provide a way for pieces of code to avoid the
constraints of the CLR. Any blocks marked as <code>unsafe</code> will not be
managed by the runtime, and it's up to the programmer to test and ensure that
the code works as expected.</p>
<samp>
 <h3>An <code>unsafe</code> block in a method</h3>
 <pre><kbd>static void</kbd> foo()
{
    <kbd>int</kbd> i = <var>10</var>;
    <kbd>unsafe</kbd>
    {
        <kbd>int</kbd> *p = &amp;i;
        System.Console.WriteLine(<var>"Value at p: "</var> + *p);
        System.Console.WriteLine(<var>"Address of p: "</var> + (<kbd>int</kbd>)p);
    }
}</pre>
</samp>
<p>As can be seen in this example, pointer dereferencing and casts are both
allowed to happen inside an <code>unsafe</code> block, such that pointer
operations within these blocks proceed much as they would under C.</p>
<h2>A graphic example: The fire effect</h2>
<p>One of the first things a budding coder wants to learn is how to make a
game, and the first stage in that journey is how to output graphics to the
screen. Among the simplest demonstrations of graphical output are the
two-dimensional colour effects: palette rotation, plasma, and the effect
being explored here, fire.</p>
<p>The effect relies on the screen being represented as a memory buffer,
running left-to-right and top-down; accessing consecutive memory locations
will run through the whole buffer in sequence. An averaging algorithm is
applied across the buffer, which runs as follows:</p>
<samp>
 <h3>Fire algorithm, applied to a memory buffer</h3>
 <pre><s>// Introduce randomness to the averaging</s>
For each X-coordinate on the bottom line
    Fill in the pixel with a random value
Next

<s>// Apply averaging filter</s>
For all other lines in the buffer
    For each X-coordinate on the line
        Total = Value of current pixel +
	        Value of pixel to the right +
		Value of pixel underneath +
		Value of pixel to the bottom left

	Avg = Total / 4

	<s>// Decrement, so lines toward the top fade to 0</s>
	Avg = Avg-1
	If (Avg &lt; 0) Avg = 0

	Value of current pixel = Avg
    Next
Next</pre>
</samp>
<p>The effect of this is that the larger values, from the line beneath, are
transferred in lesser form up the screen; combined with a forced decrement on
the averaged value, the effect is a randomised fading from high values at the
bottom, to zero at the top. With the appropriate palette to define high values
as white, going through yellow and red to black, it's easy to make this look
like a burning fire.</p>
<p>It's a situation that's ideal for pointers: dereferencing a pointer to get
the value at the current pixel, adding constants on to get to the pixels around
the current one, and then pushing the pointer along to do the next byte.</p>
<h2>Putting the effect on-screen</h2>
<p>The simplest way of using this effect to get something on the screen is to
use a Windows Form; the Form base class will handle all the window instantiation
and mouse events, leaving us to concentrate on putting data into the window.
By holding a handle to an 8-bit bitmap image, and drawing that image into the
window, the Bitmap class will do all the work of calculating palette colours
and translating them from the bitmap indices.</p>
<samp>
 <h3><code>fire.cs</code>: Rendering the fire</h3>
 <pre><kbd>using</kbd> System;
<kbd>using</kbd> System.Drawing;
<kbd>using</kbd> System.Drawing.Imaging;
<kbd>using</kbd> System.Windows.Forms;

<kbd>class</kbd> FirstForm : Form
{
    <kbd>private</kbd> Bitmap buf;        <s>// Graphic buffer</s>
    <kbd>private</kbd> Random rnd;        <s>// RNG source</s>

    <kbd>private const int</kbd> width = <var>320</var>;
    <kbd>private const int</kbd> height = <var>240</var>;

    <kbd>public</kbd> FirstForm()
    {
        <s>// Initialise an RNG for later use</s>
        rnd = <kbd>new</kbd> Random();

        <s>// Set the initial properties of the form</s>
        <kbd>this</kbd>.Text = <var>"Fire #1"</var>;
        <kbd>this</kbd>.ClientSize = <kbd>new</kbd> Size(width, height);
        <kbd>this</kbd>.MaximizeBox = <var>false</var>;
        <kbd>this</kbd>.BackColor = Color.Black;
        SetStyle(ControlStyles.Opaque, <var>true</var>);

        <s>// Nominate the paint function</s>
        <kbd>this</kbd>.Paint += <kbd>new</kbd> PaintEventHandler(<kbd>this</kbd>.DoFire);

        <s>// Generate a 320x240 bitmap, fire palette</s>
        buf = <kbd>new</kbd> Bitmap(width, height, PixelFormat.Format8bppIndexed);
        ColorPalette pal = buf.Palette;

        <s>// Fill the palette with the following 64-colour blocks:
        // Black to red, Red to yellow, Yellow to white, White
	// Since each range is 64 colours, and RGB spans 256 values,
	// utilise the <a href="http://imrannazar.com/Bitwise-Operators">left shift</a> to multiply up</s>
        <kbd>for</kbd>(<kbd>int</kbd> i=<var>0</var>; i&lt;<var>64</var>; i++)
        {
            pal.Entries[i]     = Color.FromArgb(i&lt;&lt;<var>2</var>, <var>0</var>, <var>0</var>);
            pal.Entries[i+<var>64</var>]  = Color.FromArgb(<var>255</var>, i&lt;&lt;<var>2</var>, <var>0</var>);
            pal.Entries[i+<var>128</var>] = Color.FromArgb(<var>255</var>, <var>255</var>, i&lt;&lt;<var>2</var>);
            pal.Entries[i+<var>192</var>] = Color.FromArgb(<var>255</var>, <var>255</var>, <var>255</var>);
        }
        buf.Palette = pal;
    }

    <s>// The paint function delegated to handle drawing the fire</s>
    <kbd>private void</kbd> DoFire(<kbd>object</kbd> src, PaintEventArgs e)
    {
        <s>// Lock the bitmap so we can write to it direct</s>
        BitmapData buflock = buf.LockBits(
            <kbd>new</kbd> Rectangle(Point.Empty, buf.Size),
            ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);

        <s>// Write a fire
        // This section uses pointers, and is thus deemed "unsafe"</s>
        <kbd>unsafe</kbd>
        {
            <s>// Fetch a pointer to the top scanline of the image</s>
            Byte *bufdata = (Byte*)buflock.Scan0;
            Byte *bufbottom = bufdata + ((height-1) * width);
            Byte *i; <kbd>int</kbd> v;

            <s>// Write a random bottom line as source of the fire</s>
            <kbd>for</kbd>(<kbd>int</kbd> x=<var>0</var>; x&lt;width; x++)
            {
                *(bufbottom+x) = (Byte)rnd.Next(<var>0</var>, <var>255</var>);
            }

            <s>// For each pixel in the image, average the values of
            // the pixel, the one to the right, the one underneath
            // and the one to the bottom left. Threshold to 0,
            // and write to the current position.</s>
            <kbd>for</kbd>(i=bufdata; i&lt;bufbottom; i++)
            {
                v = *i + *(i+1) + *(i+height) + *(i+height-1);
                v /= <var>4</var>;
                if(v&lt;<var>0</var>) v=<var>0</var>;
                *i = (Byte)v;
            }
        }

        <s>// Unlock ourselves out from the image and blit it to the Form</s>
        buf.UnlockBits(buflock);
        e.Graphics.DrawImageUnscaled(buf, <var>0</var>, <var>0</var>);

        <s>// Ensure that we'll be drawing another frame real soon, by
        // forcing a repaint</s>
        <kbd>this</kbd>.Invalidate();
    }

    <kbd>public static void Main</kbd>(<kbd>string</kbd>[] args)
    {
        Application.Run(<kbd>new</kbd> FirstForm());
    }
}</pre>
</samp>
<p>In the full example above, the <code>unsafe</code> block in the paint
handler is where the averaging algorithm is applied across the bitmap buffer,
through the use of pointers. By running this code for a few seconds, the
following is produced on-screen.</p>
<figure>
 <img src="/content/img/cs-pointers-sshot.png" alt="Fire algorithm screenshot">
 <figcaption>Figure 1: The fire algorithm applied to a bitmap buffer</figcaption>
</figure>
<p>So that's how it works. Some languages in the current crop forbid the use of
pointers altogether: C# allows their use, but only if you promise to keep things
clean, because the runtime won't do it for you.</p>
<p><em>Copyright Imran Nazar &lt;<a href="mailto:tf@imrannazar.com">tf@imrannazar.com</a>&gt;, 2008.</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Automated Deployment with Subversion</title>
 <link href="https://imrannazar.com/articles/svn-automated-deployment" rel="alternate" type="text/html" title="Automated Deployment with Subversion" />
 <id>https://imrannazar.com/articles/svn-automated-deployment</id>
 <summary>Version control systems and development testing servers go hand in hand; you work on your local working copy, and test on the development server. But what happens when you want to take your work live: to deploy the developments you&#039;ve completed? This article presents one way to solve that problem, by using the scripting facilities provided by Subversion.</summary>
 <category term="Articles" />
 <published>Tue, 21 Oct 2008 21:37:43 +0000</published>
 <content type="text/html"><![CDATA[
   <p>When introducing version control into a web development environment, the
process often happens gradually. Generally, one developer will set up a
repository, throw all the code in there, and maintain two working copies:
one to develop with, and one to act as the production codebase. On occasion,
these will even be the same working copy.</p>
<p>At this point, it's simple to work the version control: the developer
commits from his local working copy, and updates the "live" working copy to
the new revision. There are, of course, a couple of drawbacks to this
approach:</p>
<dl>
 <dt>No testing phase:</dt>
 <dd>Unless the developer has a testing environment set up on his local
 machine, there's no way to test code that's being written, until it's sitting
 on the production server. If the code is bug-ridden this presents a problem,
 since the live dataset is being corrupted.</dd>
 <dt>Single-developer testing:</dt>
 <dd>Even if the developer in question has a test environment set up, a new
 developer assigned to the product will not be able to test his work without
 a replica of that setup on his own machine. Ideally, a testing machine would
 be made available so that any developer could test their work without recourse
 to a specialised setup on their own computer.</dd>
 <dt>Manual deployment:</dt>
 <dd>Once a developer is satisfied that their work will stand up in production,
 whether this be tested with a common testbed or on their own workstation, the
 repository now has to be <code>export</code>ed, and copied to the live server.
 Depending on the convolutions required to connect to the live server, this
 can be a tedious and/or complicated process.</dd>
</dl>
<p>This article discusses the next phase of repository setup: separation of the
testing and production environments, and automated updating of both.</p>
<h2>Subversion Hooks</h2>
<p>If a common testing server is introduced into the process, and a working
copy of the codebase is placed into testing, it's quite simple for a developer
to test code: simply commit their working copy to the repository, and update
the copy on the testing server.</p>
<p>As with a standard production server, however, a manual step remains: the
testing copy has to be updated before it can be used. The commit process itself
must somehow automatically update the testing copy if the test server is to be
of any real use. Fortunately, Subversion provides a facility to perform actions
as part of a commit, with the <em>hook</em> scripting system.</p>
<p>A Subversion hook is a script that is run by the Subversion server whenever
a particular thing happens. There are a few actions which can trigger a hook,
but we're only interested in the <code>commit</code> hook scripts:</p>
<ul>
 <li><strong>start-commit</strong>: Run before Subversion opens a database
 transaction to store the updated work. If this script returns an error, the
 commit fails before it even began.</li>
 <li><strong>pre-commit</strong>: Run just before Subversion writes the commit
 into the database. If this errors, the commit is reversed, and not saved.</li>
 <li><strong>post-commit</strong>: Run just after a revision has been committed
 and has a revision number. Any errors produced by this script are ignored by
 the Subversion server.</li>
</ul>
<p>For the automated deployment process, the <code>post-commit</code> hook will
be used to ensure that only successful commits are replicated to the testing
and/or live servers.</p>
<h2>Updating the testing environment</h2>
<p>The <code>post-commit</code> hook script is given two parameters by the
Subversion server: the path to the repository that's just been updated, and the
revision number of the update. Since the hook script is specific to a
repository, it can be customised:</p>
<figure class="invertable">
 <img src="/content/img/svn-deploy-testupdate.gif" alt="Updating the testing environment">
 <figcaption>Figure 1: Control flow for a commit with automatic testing environment update</figcaption>
</figure>
<p>The hook scripts can be in any language usable by the server, including
Bash, Python or Perl; I've used Bash for the purposes of this article, so the
above control flow would translate into the following <code>post-commit</code> hook:</p>
<samp>
 <h3 class="title">Automated update of a test-server working copy</h3>
 <pre><s>#!/bin/bash</s>
<kbd>REPO</kbd>=<var>"$1"</var>
<kbd>REV</kbd>=<var>"$2"</var>

<kbd>TEST_SERVER</kbd>=<var>"192.168.1.55"</var>

<s># Update the working copy on the test server</s>
ssh -l root <kbd>$TEST_SERVER</kbd> -t <var>"cd /var/www &amp;&amp; svn up"</var></pre>
</samp>
<p>Note in the above example that the testing environment is accessed by
<code>ssh</code>, which means that the <code>root</code> user on the testing
server must know the public key of the Subversion server's user account. For
example, if the Subversion repositories are accessed by WebDAV through Apache,
and the Apache process is running as user <code>nobody</code>, the user
calling the <code>post-commit</code> hook is <code>nobody@SVN_SERVER</code>,
and a public/private <code>ssh</code> key pair must be prepared for this user
and copied to the testing server.</p>
<h2>Deployment notification</h2>
<p>The control flow in the above example updates the testing environment every
time an update is committed to the repo. What's needed next is a method of
automatically pushing committed updates to the production system, using some
part of the commit action as a trigger. The ideal vector for this is the commit
message: the description entered by the developer as the reason for this
update.</p>
<p>A command is available as part of the Subversion distribution to examine
the properties of a repository: <code>svnlook</code>. This can be used to 
check the commit message for the latest revision, and look for a signal
inserted by the developer to indicate a request for deployment.</p>
<figure class="invertable">
 <img src="/content/img/svn-deploy-deploytag.gif" alt="Checking for deployment requests">
 <figcaption>Figure 2: Control flow for a commit with deployment request</figcaption>
</figure>
<p>The deployment signal can be as simple as a block of text inside the commit
message: if the <code>post-commit</code> hook detects this block of text in
the message, it will perform the deployment. As stated above, <code>svnlook</code>
can be used to look at the commit message:</p>
<samp>
 <h3 class="title">Checking the commit message: <code>svnlook</code></h3>
 <pre><kbd>PROD_SERVER</kbd>=<var>"172.16.16.1"</var>
 
if ( svnlook log -r <kbd>$REV</kbd> <kbd>$REPO</kbd> | grep <var>"~~DEPLOY~~"</var> )
then
    /usr/local/bin/svn-deploy <kbd>$REPO</kbd> <kbd>$REV</kbd> <var>"root@<kbd>${PROD_SERVER}</kbd>:/var/www"</span>
fi</pre>
</samp>
<p>By asking for a specific revision using the <code>-r</code> flag, we can
ensure that the revision number passed into the hook script is the one that
gets checked. Even though this number should be the latest revision in the
repo, it's best to make use of the revision number when it's given.</p>
<h2>Performing a deployment</h2>
<p>One way to deploy a Subversion repo is to simply keep a working copy as the
production environment: in this situation, deployment is as easy as updating
the production working copy. The disadvantage of this is that the Subversion
control files and directories will be available in production; since these
control files include the text base of the working copy, this exposes the
backend code and database interfaces in plain text files.</p>
<p>Subversion provides a command targeted to producing a "clean" copy of the
repository: a dump of the contents, without <code>.svn</code> directories
littering the structure. That command is <code>svn export</code>:</p>
<samp>
 <h3 class="title">Exporting the contents of a repo: <code>svn export</code></h3>
 <pre>svn export -r <kbd>$REV</kbd> <var>"file://$REPO"</var> /destination/path</pre>
</samp>
<p>By asking for a specific revision, as with <code>svnlook</code>, we make
sure that the revision passed to the hook script is the one exported. Once the
export has occurred, this can be uploaded to the production server, or
synchronised with <code>rsync</code> in whatever way is required.</p>
<h2>Putting things together</h2>
<p>With these components, we can put together the hook and deployment scripts:</p>
<samp>
 <h3 class="title"><code>post-commit</code>: Hook script</h3>
 <pre><s>#!/bin/bash</s>
<kbd>REPO</kbd>=<var>"$1"</var>
<kbd>REV</kbd>=<var>"$2"</var>

<kbd>TEST_SERVER</kbd>=<var>"192.168.1.55"</var>
<kbd>PROD_SERVER</kbd>=<var>"172.16.16.1"</var>

<s># Update the working copy on the test server</s>
ssh -l root <kbd>$TEST_SERVER</kbd> -t <var>"cd /var/www &amp;&amp; svn up"</var>

<s># Check for a deployment signal</s>
if ( svnlook log -r <kbd>$REV</kbd> <kbd>$REPO</kbd> | grep <var>"~~DEPLOY~~"</var> )
then
    /usr/local/bin/svn-deploy <kbd>$REPO</kbd> <kbd>$REV</kbd> <var>"root@<kbd>${PROD_SERVER}</kbd>:/var/www"</span>
fi</pre>
</samp>
<samp>
 <h3 class="title"><code>svn-deploy</code>: Example deployment script</h3>
 <pre><s>#!/bin/bash</s>
<kbd>REPO</kbd>=<var>"$1"</var>
<kbd>REV</kbd>=<var>"$2"</var>
<kbd>TARGET</kbd>=<var>"$3"</var>

<s># Connect to datacentre VPN</s>
sudo pppd call datacentre nodetach
sudo route add -net 172.16.16.0/24 dev ppp0

<s># Export the repo</s>
rm -rf /tmp/export
svn export -r <kbd>$REV</kbd> <var>"file://$REPO"</var> /tmp/export

<s># Synchronise with production</s>
rsync -az -e ssh /tmp/export/* <kbd>$TARGET</kbd></pre>
</samp>
<p>In this particular case, the production server is behind a VPN at the
datacentre, which must be tunneled through for the deployment to occur.</p>
<h2>Running a deployment: The developer's view</h2>
<p>Once the post-commit hook has been put into place by a repository
administrator, any developer with a checked-out copy of the repo is free to
commit updates; any update will cause the testing environment copy to be
updated, allowing for a common testing point.</p>
<p>Deployment is signalled as part of the commit message for a revision, as
below:</p>
<samp>
 <h3>Sample commit message with deployment</h3>
 <pre>- Frontend: Checkout process: CC payment handling added
- Admin: Orders: Status dropdown now autosaves on change
~~DEPLOY~~</pre>
</samp>
<p>As can be seen above, the deployment code "<code>~~DEPLOY~~</code>" must be
present in the commit message for deployment to be signalled. Any files changed
as part of the commit will be saved in the new revision, before deployment; the
copy to production will include all files in the repository that have changed
since the last deployment.</p>
<h2>Nice-to-haves: possible advancements</h2>
<p>There are a few ways in which the above simple scripts could be
enhanced.</p>
<dl>
 <dt>Branch handling:</dt>
 <dd>The scripts assume that the codebase is stored in its entirety in
 the repository, and only the trunk of the codebase is in the repo. If the
 repo is structured in a trunk-and-branch fashion, everything will be exported
 and deployed. By using a commit-message signal similar to the deployment
 signal, it should be possible to test a particular branch, by updating the
 trunk on the testing server and then copying the contents of the
 signalled branch over the top.</dd>
 <dt>Changelog production:</dt>
 <dd>By checking the commit messages using <code>svnlook</code>, it's
 possible to generate a Changelog for the repository: a list of revisions
 ordered by date, showing what changes were made to the codebase at each
 point. It's also possible to email the Changelog to the developers, if this
 is desired.</dd>
 <dt>Database structure updates:</dt>
 <dd><code>svnlook</code> also allows the hook script to look at which files
 were modified with the commit. If a pre-determined SQL file is modified, this
 can be used to signal a change in database structure, and the changes can
 be applied to the production database through an <code>ssh</code> connection.</dd>
</dl>
<p>Each of these possible changes would introduce complexity into the automated
deployment system; for now, the scripts presented here are a simple way to
speed up the testing and deployment process.</p>
<p><em>Copyright Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Building Complex Emails with PHP</title>
 <link href="https://imrannazar.com/articles/php-mime-mail" rel="alternate" type="text/html" title="Building Complex Emails with PHP" />
 <id>https://imrannazar.com/articles/php-mime-mail</id>
 <summary>The first script that a budding PHP developer builds is often a tool to send simple email messages from a website, with a couple of paragraphs of text inside. What these scripts lack is the ability to send HTML-formatted emails, or to attach documents and other files to the message. In this article, I cover the MIME standard for building complex emails, and how to format and send a MIME-compliant email message in PHP.</summary>
 <category term="Articles" />
 <published>Sun, 10 Aug 2008 15:17:50 +0000</published>
 <content type="text/html"><![CDATA[
   <p>One of the first things that a newcomer to PHP learns is how to send a
simple email: using the <code>mail</code> function to send a few paragraphs
of text to an email address. This is an easy and functional way to send
status messages and other small emails, but there are disadvantages:</p>
<dl>
 <dt>Unformatted text:</dt>
 <dd>With plain text emails, only the most rudimentary structure can be
 given to a message; there's no inherent way to insert a heading or a
 bullet-point list. If HTML were allowed in the email, for example, this
 formatting could be provided to the message.</dd>
 <dt>No attachments:</dt>
 <dd>Because the email is a single plain-text message, there is no way to
 provide additional documents or other files in the body of the message.
 A compromise is to place the files in question on the public Web, and
 provide links to the files, but this also compromises the security of
 the documents.</dd>
</dl>
<p>These problems are not just limitations of PHP's mailing routines: they
are limitations of the email transport mechanism. In order to get around them,
a devious scheme was standardised in the 1990s.</p>
<h2>Multipurpose Internet Mail Extensions</h2>
<p>The MIME standard was designed to work inside the existing email transport
system; as such, it doesn't need any special connection methods, and no
complicated networking is required on the part of the developer. Instead, MIME
allows for multi-part messages by inserting all the parts into a plain-text
email, and separating the parts by a boundary.</p>
<samp>
 <h3>Structure: Basic boundaries</h3>
 <pre>Text outside the boundary (part #0)
--BOUNDARY
Part #1
--BOUNDARY
Part #2
--BOUNDARY--</pre>
</samp>
<p>As can be seen in the example above, two hyphens precede all instances of 
the boundary, and one boundary forms the end of one part and the start of
the next. The end of the last part is denoted by two hyphens after the boundary
closing that part.</p>
<p>The basic structure outlined above allows for the separation of parts, but
all it can provide is multiple plain-text messages combined into one. To allow
for more complex information to be encoded, headers must be provided in
association with each part.</p>
<h2>MIME Headers</h2>
<p>An issue arises with the boundary structure: how is the email reading client
to know which lines denote the boundary for a part, and which are simply part
of the message? The client can be informed of which boundary is being used by
providing a header for the message in total. Headers are often used to denote
the originator of the message, the software version of the sending server, and
other such information which may be pertinent to the client; the MIME boundary
can be added to this.</p>
<samp>
 <h3>Headers: MIME message boundary</h3>
 <pre>From: "Imran Nazar" &lt;tf@oopsilon.com&gt;
MIME-Version: 1.0
Content-type: multipart/mixed; boundary="BOUNDARY"
<em>&lt;blank line&gt;</em>
Message body</pre>
</samp>
<p>The <code>Content-type</code> header tells the email client what kind of
data is provided in the message; the text following <code>Content-type</code>
is known as a MIME type. The concept of MIME types has been extended for use
beyond email, and is now commonly provided by Web and file servers in response
to a request for data.</p>
<p>The MIME type provided with a chunk of data can be used to identify the
data in question. There are various classes of data that have MIME types
associated with them, and subdefinitions for each class. The class and subclass
of data are given in <code>major/minor</code> format; a few examples are
provided below.</p>
<figure>
 <table>
  <thead><tr><th>Major</th><th>Minor</th><th>Full type</th><th>Data</th></tr></thead>
  <tbody>
   <tr><td colspan="4"><strong>Text documents</strong></td></tr>
   <tr><td>text</td><td>plain</td><td>text/plain</td><td>Plain text documents</td></tr>
   <tr><td>text</td><td>html</td><td>text/html</td><td>HTML documents</td></tr>
   <tr><td>text</td><td>csv</td><td>text/csv</td><td>Comma-separated data files</td></td>
   <tr><td colspan="4"><strong>Images</strong></td></tr>
   <tr><td>image</td><td>jpeg</td><td>image/jpeg</td><td>JPEG-formatted images</td></tr>
   <tr><td>image</td><td>png</td><td>image/png</td><td>PNG-formatted images</td></tr>
   <tr><td colspan="4"><strong>Application-specific types</strong></td></tr>
   <tr><td>application</td><td>pdf</td><td>application/pdf</td><td>Portable Document Format (PDF)</td></tr>
   <tr><td>application</td><td>zip</td><td>application/zip</td><td>PKZIP compressed archives</td></tr>
   <tr><td>application</td><td>msword</td><td>application/msword</td><td>MS Word documents</td></tr>
   <tr><td colspan="4"><strong>Types with multiple components</strong></td></tr>
   <tr><td>multipart</td><td>form-data</td><td>multipart/form-data</td><td>Web forms with uploaded files</td></tr>
   <tr><td>multipart</td><td>mixed</td><td>multipart/mixed</td><td>Messages with many types of component</td></tr>
  </tbody>
 </table>
 <figcaption>Table 1: Sample MIME types</figcaption>
</figure>
<p>As can be seen above, the <code>multipart/mixed</code> MIME type tells the
email reader that each part of the message can be of a different type. Just as
with the message, each part can have a header and a body. Taking this into
account, a fuller MIME-compliant message can be built.</p>
<samp>
 <h3>Multipart emails with headers</h3>
 <pre>This is part #0.
--BOUNDARY
Content-type: text/html

This is part #1.
--BOUNDARY
Content-type: text/csv

id,content,date
"1","This is part #2.","2008-08-10"
--BOUNDARY--</pre>
</samp>
<h2>Attachments and Content Headers</h2>
<p>We've seen how to put multiple types of message into one email, but this is
not sufficient for attaching documents and other files to an email message.
There are two major problems with inserting documents into an email:</p>
<dl>
 <dt>Naming:</dt>
 <dd>As can be seen above, files can be inserted into an email as a MIME part,
 but they are not given a filename, and are not treated as attachments. This
 problem is solved by inserting another header along with the part's
 <code>Content-type</code>, called <code>Content-disposition</code>.</dd>
 <dt>Encoding:</dt>
 <dd>An email message has to be readable in its entirety by any mailserver
 that happens across it. Because mailservers may run in many places, under
 many languages and character sets, a binary data file is not guaranteed to
 make it to the destination intact: it has to be encoded into a more basic
 character set, and the email client has to be told how to decode the
 resultant email part. This is done with a third header, called
 <code>Content-transfer-encoding</code>.</dd>
</dl>
<p>The <code>Content-disposition</code> attached to a message part can be one
of two types: <code>inline</code>, meaning this type is to be shown as part
of the email, and <code>attachment</code>, which denotes a file attached for
download. If it's an <code>attachment</code>, a <code>filename</code> can be
provided as a parameter to the <code>Content-disposition</code> header. Using
this header, we can make the CSV data file in the above example into an
attachment:</p>
<samp>
 <h3>Multipart emails with disposition</h3>
 <pre>This is part #0.
--BOUNDARY
Content-type: text/html
Content-disposition: inline

This is part #1.
--BOUNDARY
Content-type: text/csv
Content-disposition: attachment; filename="data.csv"

id,content,date
"1","This is part #2.","2008-08-10"
--BOUNDARY--</pre>
</samp>
<p>This takes care of the first problem with attaching files to an email, but
the second remains: encoding the attachment into a transferable format. There
are two major encoding methods allowed by the MIME standard:</p>
<ul>
 <li><code>quoted-printable</code>: a discriminate encoding, which allows
 standard text through without encoding, but translates non-standard characters
 into their hexadecimal ordinal values;</li>
 <li><code>base64</code>: an indiscriminate encoding, which takes the whole
 stream of data as one number, and translates it a chunk at a time, three bytes
 translating into a 4-character block.</li>
</ul>
<p>The <code>base64</code> encoding is generally easier to produce, since the
<code>quoted-printable</code> encoding requires specialised translation tables.
With <code>base64</code>, the data is broken up into 48-byte "lines", and
encoded into 64-character lines before insertion into the email.</p>
<p>Once an encoding has been picked, it should be provided in the header for
the message part, as shown in the below example.</p>
<samp>
 <h3>Attaching a binary file in base64 encoding</h3>
 <pre>Content-type: image/gif
Content-disposition: attachment; filename="text-icon.gif"
Content-transfer-encoding: base64

R0lGODlhIAAgAKIEAISEhMbGxgAAAP///////wAAAAAAAAAAACH5BAEAAAQALAAA
AAAgACAAAAOaSKoi08/BKeW6Cgyg+e7gJwICRmjOM6hs6q5kUF7o+rZ2vgkypq3A
oHA4kPVoxCTROFv8lNAir5mxNa7ESorpi0a5yMg15QU7vVBzFZ1Un9jtaVeMRbuf
8OA9P9zTx4CAK358QH6BiIJSR2eFhnJhiZJbkI2Oi1Rvf5N1hI6ehYeKZZVrl6Jj
bKB8q3luJwGxsrO0taUXnLkXCQA7</pre>
</samp>
<p>Now we have all the pieces of the puzzle: the ability to create an email
message with multiple parts, and a way to encode and attach files to the
email. It's just a matter of implementation.</p>
<h2>Using PHP to send MIME-compliant emails</h2>
<p>With the information above, implementation is no issue. The only problem
presented is how to define the MIME type of an arbitrary attachment.
Fortunately, UNIX systems provide the <code>file</code> command, which can
read any file and work out the MIME type of its contents. On a Windows server,
no such analogue exists, but it is possible to obtain <code>file</code> through
Microsoft Services for Unix, or UnxUtils.</p>
<p>A MIME-compliant email solution is provided below, making use of this tactic
and the information presented in this article.</p>
<samp>
 <h3>mimemail.php: Mail-building class for PHP</h3>
 <pre><kbd>define</kbd>(<var>'MIMEMAIL_HTML'</var>, <var>1</var>);
<kbd>define</kbd>(<var>'MIMEMAIL_ATTACH'</var>, <var>2</var>);
<kbd>define</kbd>(<var>'MIMEMAIL_TEXT'</var>, <var>3</var>);

<kbd>class</kbd> MIMEMail
{
    <kbd>private</kbd> $plaintext;
    <kbd>private</kbd> $output;
    <kbd>private</kbd> $headers;
    <kbd>private</kbd> $boundary;

    <kbd>public function</kbd> __construct()
    {
        $<kbd>this</kbd>-&gt;output = <var>''</var>;
        $<kbd>this</kbd>-&gt;headers = <var>''</var>;
        $<kbd>this</kbd>-&gt;boundary = <kbd>md5</kbd>(<kbd>microtime</kbd>());
        $<kbd>this</kbd>-&gt;plaintext = <var>0</var>;
    }

    <s>// add: Add a part to the email
    // Parameters: type (Constant) - MIMEMAIL_TEXT, MIMEMAIL_HTML, MIMEMAIL_ATTACH
    //             name (String)   - Contents of email part if TEXT or HTML
    //                             - Attached name of file if ATTACH
    //             value (String)  - Source name of file if ATTACH</s>
    <kbd>public function</kbd> add($type, $name, $value=<var>''</var>)
    {
        <kbd>switch</kbd>($type)
        {
            <kbd>case</kbd> <var>MIMEMAIL_TEXT</var>:
                $<kbd>this</kbd>-&gt;plaintext = (<kbd>strlen</kbd>($<kbd>this</kbd>-&gt;output))?<var>0</var>:<var>1</var>;
                $<kbd>this</kbd>-&gt;output = <var>"<s>{$name}</s>\r\n"</var> . $<kbd>this</kbd>-&gt;output;
                <kbd>break</kbd>;

            <kbd>case</kbd> <var>MIMEMAIL_HTML</var>:
                $<kbd>this</kbd>-&gt;plaintext = <var>0</var>;
                $<kbd>this</kbd>-&gt;writePartHeader($type, <var>"text/html"</var>);
                $<kbd>this</kbd>-&gt;output .= <var>"<s>{$name}</s>\r\n"</var>;
                <kbd>break</kbd>;

            <kbd>case</kbd> <var>MIMEMAIL_ATTACH</var>:
                $<kbd>this</kbd>-&gt;plaintext = <var>0</var>;
                <kbd>if</kbd>(<kbd>is_file</kbd>($value))
                {
		    <s>// If the file exists, get its MIME type from `file`
		    // NOTE: This will only work on systems which provide `file`: Unix, Windows/SFU</s>
                    $mime = <kbd>trim</kbd>(<kbd>exec</kbd>(<var>'file -bi '</var>.<kbd>escapeshellarg</kbd>($value)));
                    <kbd>if</kbd>($mime) $<kbd>this</kbd>-&gt;writePartHeader($type, $name, $mime);
                    <kbd>else</kbd> $<kbd>this</kbd>-&gt;writePartHeader($type, $name);

                    $b64 = <kbd>base64_encode</kbd>(<kbd>file_get_contents</kbd>($value));

                    <s>// Cut up the encoded file into 64-character pieces</s>
                    $i = <var>0</var>;
                    <kbd>while</kbd>($i &lt; <kbd>strlen</kbd>($b64))
                    {
                        $<kbd>this</kbd>-&gt;output .= <kbd>substr</kbd>($b64, $i, <var>64</var>);
                        $<kbd>this</kbd>-&gt;output .= <var>"\r\n"</var>;
                        $i += <var>64</var>;
                    }
                }
                <kbd>break</kbd>;
        }
    }

    <s>// addHeader: Provide additional message headers (Cc, Bcc)</s>
    <kbd>public function</kbd> addHeader($name, $value)
    {
        $<kbd>this</kbd>-&gt;headers .= <var>"<s>{$name}</s>: <s>{$value}</s>\r\n"</var>;
    }

    <s>// send: Complete and send the message</s>
    <kbd>public function</kbd> send($from, $to, $subject)
    {
        $<kbd>this</kbd>-&gt;endMessage($from);
        <kbd>return mail</kbd>($to, $subject, $<kbd>this</kbd>-&gt;output, $<kbd>this</kbd>-&gt;headers);
    }

    <s>// writePartHeader: Helper function to add part headers</s>
    <kbd>private function</kbd> writePartHeader($type, $name, $mime=<var>'application/octet-stream'</var>)
    {
        $<kbd>this</kbd>-&gt;output .= <var>"--<s>{$<kbd>this</kbd>-&gt;boundary}</s>\r\n"</var>;
        <kbd>switch</kbd>($type)
        {
            <kbd>case</kbd> <var>MIMEMAIL_HTML</var>:
                $<kbd>this</kbd>-&gt;output .= <var>"Content-type: <s>{$name}</s>; charset=\"iso8859-1\"\r\n"</var>;
                <kbd>break</kbd>;

            <kbd>case</kbd> <var>MIMEMAIL_ATTACH</var>:
                $<kbd>this</kbd>-&gt;output .= <var>"Content-type: <s>{$mime}</s>\r\n"</var>;
                $<kbd>this</kbd>-&gt;output .= <var>"Content-disposition: attachment; filename=\"<s>{$name}</s>\"\r\n"</var>;
                $<kbd>this</kbd>-&gt;output .= <var>"Content-transfer-encoding: base64\r\n"</var>;
                break;
        }

        $<kbd>this</kbd>-&gt;output .= <var>"\r\n"</var>;
    }

    <s>// endMessage: Helper function to build message headers</s>
    <kbd>private function</kbd> endMessage($from)
    {
        if(!$<kbd>this</kbd>-&gt;plaintext)
        {
            $<kbd>this</kbd>-&gt;output .= <var>"--<s>{$<kbd>this</kbd>-&gt;boundary}</s>--\r\n"</var>;

            $<kbd>this</kbd>-&gt;headers .= <var>"MIME-Version: 1.0\r\n"</var>;
            $<kbd>this</kbd>-&gt;headers .= <var>"Content-type: multipart/mixed; boundary=\"<s>{$<kbd>this</kbd>-&gt;boundary}</s>\"\r\n"</var>;
            $<kbd>this</kbd>-&gt;headers .= <var>"Content-length: "</var>.<kbd>strlen</kbd>($<kbd>this</kbd>-&gt;output).<var>"\r\n"</var>;
        }
        
        $<kbd>this</kbd>-&gt;headers .= <var>"From: <s>{$from}</s>\r\n"</var>;
        $<kbd>this</kbd>-&gt;headers .= <var>"X-Mailer: MIME-Mail v0.03, 20070419\r\n\r\n"</var>;
    }
}</pre>
</samp>
<samp>
 <h3>Example usage of mimemail</h3>
 <pre><kbd>include</kbd>(<var>'mimemail.php'</var>);

$m = <kbd>new</kbd> MIMEMail();

<s>// Provide the message body</s>
$m-&gt;add(<var>MIMEMAIL_TEXT</var>, <var>'An example email message.'</var>);

<s>// Attach file 'icons/txt.gif', and call it 'text-icon.gif' in the email</s>
$m-&gt;add(<var>MIMEMAIL_ATTACH</var>, <var>'text-icon.gif'</var>, <var>'/var/www/icons/txt.gif'</var>);

<s>// Send to the author</s>
$m-&gt;send(<var>'noreply@oopsilon.com'</var>, <var>'"Imran Nazar" &lt;tf@oopsilon.com&gt;'</var>, <var>'Test message'</var>);</pre>
</samp>
<p>Download the script: <a href="http://oopsilon.com/html/mimemail-20070419.phps">mimemail.php</a></p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Extended Text Mode on the Commodore 64</title>
 <link href="https://imrannazar.com/articles/c64-extended-text-mode" rel="alternate" type="text/html" title="Extended Text Mode on the Commodore 64" />
 <id>https://imrannazar.com/articles/c64-extended-text-mode</id>
 <summary>When you mention the Commodore 64, most people think that it&#039;s an obsolete computer from the 80s which no-one could ever use nowadays. One of the major problems is that you can&#039;t fit enough information onto a C64&#039;s screen: the standard size of a work terminal is 80 characters by 25 lines, and 40x25 just isn&#039;t enough. In the first part of a series (which may take some time to complete), I look into rendering an 80x25 text screen on the Commodore 64, and how it can be done.</summary>
 <category term="Articles" />
 <published>Sun, 03 Aug 2008 00:00:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>I sometimes wonder what it would take for a computer of 80s vintage to be
a viable work terminal in today's world. After some thought, I came up with
two things that an old computer would need:</p>
<dl>
 <dt>Internet access:</dt>
 <dd>Getting data to an old computer without the Internet is a thankless
 task, involving microcassette recordings and funky formats of floppy disc
 which are unreadable in a PC. Getting the data back off the computer in
 question is even more of a problem; it's simply orders of magnitude easier
 to connect to a standard network and transfer through that.</dd>
 <dt>Display compatibility:</dt>
 <dd>Computers of such vintage as the Commodore 64 and the Spectrum have
 a variety of display modes, but none of them put a great deal of information
 on the screen. To viably communicate with a computer of a different type,
 such as a Linux server, it's a prerequisite to extend the text mode
 capabilities of the computer, and get something approaching a usable terminal.</dd>
</dl>
<p>This article is intended to be part 1 of a series, in which a Commodore
64 will be set up to act as a standard Unix-compatible terminal. The first
step in that ambitious program is to provide a reasonable text display on
the Commodore 64.</p>
<h2>The C64's video modes</h2>
<p>The Commodore 64 has a display resolution of 320 by 200 pixels, a
resolution which will be familiar to any PC programmer who has dealt with the
VGA display modes. The C64 provides two basic types of display mode: bitmapped
and tiled. Each of these has the ability to display pixels in one colour
against a background of another colour. In both modes, the display is broken
up logically into 8x8-pixel "tiles"; the difference is in how these are
handled and how graphics are drawn in the two modes.</p>
<p>In tiled mode, also called "text mode", the screen has a tile-resolution
of 40 wide by 25 high, and the display is built in the following manner.</p>
<figure class="invertable">
 <img src="/content/img/c64-80x25-tilemode.gif" alt="Tiled mode">
 <figcaption>Figure 1a: Display in tiled mode</figcaption>
</figure>
<p>The tile-address buffer, often called "Screen Memory", is a 1000-byte
region of memory where each byte refers to an 8x8 block on screen. In order
to get the bitmap data for the display, the video circuit uses the value in
screen memory as a pointer into the tile-data buffer, called "Character Memory".
When the computer is first started, this memory contains the shapes of letters
and numbers which can be used to draw text on the screen; for this reason,
tiled mode is often referred to as "40x25 text mode".</p>
<p>Tiled mode allows for each 8x8 block of pixels to have a different
foreground colour; any bits in the tile which are set to "1" will be drawn
in the foreground colour for that tile. Just like screen memory, a 1000-byte
region is set aside for the tile-colour buffer, called "Colour Memory", which
provides the foreground colours for each tile. The background is the same across
the whole screen, and any "0" bits will be drawn in the global background
colour.</p>
<p>Bitmapped mode skips the tile-addressing step in the display process,
opting instead for a unified buffer of bitmap data. An 8000-byte region is
set aside for the display of 320x200 bits, with blocks of 8x8 still being
addressed as a tile.</p>
<figure class="invertable">
 <img src="/content/img/c64-80x25-bitmapmode.gif" alt="Drawing in bitmapped mode">
 <figcaption>Figure 1b: Drawing in bitmapped mode</figcaption>
</figure>
<p>Just as with tiled mode, each 8x8 block can have a different foreground
colour. In the case of bitmapped mode, however, a block can also have its
own background colour, which will be used instead of the global background
if any "0" bits are encountered in the bitmap.</p>
<h2>The options</h2>
<p>So we have two options for drawing to the C64's screen. Either of these
could be used for the rendering of an 80x25 text mode, but there are a few
arguments against the use of tiled mode:</p>
<dl>
 <dt>It's more complex:</dt>
 <dd>Drawing to a bitmapped screen involves writing the appropriate bits
 to a piece of the bitmap buffer. In tiled mode, a tile has to be written
 into Character Memory, and Screen Memory has to be updated to reflect
 the new tile.</dd>
 <dt>It's slower to work with:</dt>
 <dd>Because of the above complexity of tiled mode, more memory has to be
 worked with to set a tile up correctly, which means it takes more time to
 write text out to screen.</dd>
 <dt>It's not big enough:</dt>
 <dd>By placing an 80x25 "extended text mode" into 40x25 tiled mode, each
 tile can hold two characters. In theory, there are over 65,000 combinations
 of two-character tiles, any of which could show up on screen; tiled mode
 can only deal with 256 of these combinations on screen at the same time,
 before some hacks have to be employed.</dd>
</dl>
<p>For these reasons, it's simpler to use bitmapped mode to draw the
characters. What's required now is a readable font that can be used by
the rendering system.</p>
<h2>The font</h2>
<p>Most terminal systems use a mono-spaced font, primarily because it makes
calculations easier regarding text placement and size. This extended text
mode will be no exception: in order to fit an 80x25 text screen into a
320x200 graphical display, each character must be 4x8 pixels: in other words,
each of the 8x8 tiles must be cut down the middle and a character placed in
each half.</p>
<p>What this doesn't take into account is the need to seperate characters:
if the font is made up of 4x8-pixel glyphs, each character in a line of text
will be joined to the next, without any seperation. What is instead needed is
a pixel of seperation between characters: this means that the font will
consist of 3x7-pixel glyphs in 4x8 boxes.</p>
<p>On such a small scale, designing a legible font is tricky: distinguishing
between zero (0) and capital O is difficult at the best of times, and the
difference between one (1), small L and the vertical pipe (|) can be even
more of a problem. I'm not a font designer, so I opted instead to use the
font glyphs from Novaterm, a terminal program for the C64.</p>
<figure>
 <img src="/content/img/c64-80x25-font.png" alt="The font">
 <figcaption>Figure 2: 3x7 pixel font, Novaterm's "ansi81"</figcaption>
</figure>
<p>In order to use this font programmatically, each character has to be broken
down into its constituent bits, and reconstituted as data. Because the glyphs
are 4 pixels wide, the resultant data will be 4 bits wide.</p>
<h2>The process</h2>
<p>With a font and a bitmap mode, we can now draw text to the bitmap.
Unfortunately, it's not quite as easy as writing one character to each tile,
because there are only 40 tiles' worth of space across the screen. Instead,
two characters have to be put inside one tile-space. This involves shifting
the bitmap values for the "left" character across, and combining them with
the "right" character.</p>
<figure class="invertable">
 <img src="/content/img/c64-80x25-twochar.gif" alt="Drawing into one tile">
 <figcaption>Figure 3: Drawing two characters in one tile</figcaption>
</figure>
<p>In BASIC code, this could be represented as follows, assuming that the
<code>FONT</code> two-dimensional array represents the 3x7 Novaterm font:</p>
<samp>
 <h3 class="title">Rendering "He" in BASIC</h3>
 <pre>LET CH1 = 72: <s>REM "H"</s>
LET CH2 = 101: <s>REM "e"</s>
FOR A = 0 TO 7
  OUT(A) = (FONT(CH1)(A) * 16) + FONT(CH2)(A)
NEXT A</pre>
</samp>
<p>By using a "cursor" position to keep track of where on the screen tiles
must be filled, it's relatively straightforward to use the technique above
for rendering text two characters at a time. The problem arises when a string
of text contains an odd number of characters: not only does the renderer have
to fill half a tile instead of a full tile, but the next string will start
halfway through the tile in question. Because of this, the rendering function
becomes more complex:</p>
<ul>
 <li>Check whether we're starting halfway through a tile. If so, fill in the
 right half of the existing on-screen tile with the first character bitmap.
 If not, skip this step altogether.</li>
 <li>The main rendering loop: For each pair of characters in the string
 (starting with the second character if step 1 was performed), build a tile
 and draw it to screen. Do this until there are either 1 or 0 characters left
 to render.</li>
 <li>If there's one character left, fill in the left half of a blank tile,
 and draw that to screen. If there are no characters left to draw, skip this
 step.</li>
</ul>
<p>The top and bottom pieces of algorithm are extensions of the main rendering
loop, and won't be covered here in much detail. Instead, I'll provide an
interpretation of the insides of the main loop, in pseudo-C++.</p>
<samp>
 <h3 class="title">Rendering a two-character tile</h3>
 <pre>BYTE *bitmap;     <s>// 8000-byte bitmap to render to</s>
BYTE *font;       <s>// 2048 bytes font data, 8 bytes per char</s>
char t1, t2;      <s>// Text to render (two characters long)</s>

int X, Y;         <s>// Current cursor position</s>

<s>// Calculate position of destination tile in the bitmap
// Each tile is 8 bytes long</s>
BYTE *tile = bitmap + ((Y * 80 + X) * 8);

for(int i=0; i&lt;8; i++)
{
    <s>// Retrieve font data for this line of the bitmap</s>
    BYTE ch1 = font[t1 * 8 + i];
    BYTE ch2 = font[t2 * 8 + i];

    <s>// Calculate final tile contents</s>
    tile[i] = (ch1 * 16) + ch2;
}</pre>
</samp>
<p>In the case of the top and bottom parts of the algorithm, either <code>ch1</code>
or <code>ch2</code> is not used in the final tile; otherwise, the code for
these parts is as above.</p>
<h2>The implementation</h2>
<p>There are a few things that need to be considered when taking this algorithm
to the Commodore 64, in order to cope with the restrictions of the platform.</p>
<h3>Font data:</h3>
<p>The algorithm outlined above takes two characters from the font data, and
shifts the "left" one over by 4 bits before tacking it to the "right"
character. This step can be eliminated by keeping a pre-shifted copy of the
font data as a seperate buffer to the original, which means that building a
cell is merely a matter of finding one character in the original font, and
the other in the shifted font, then adding the two values.</p>
<h3>Initial screen colour:</h3>
<p>As mentioned above, each tile in bitmap mode can maintain its own foreground
and background colour. The values for each tile's colours are stored in Colour
Memory, one byte for each tile: the background colour code (between 0 and 15)
is stored as the lower half of the byte, and the foreground code as the upper
half.</p>
<p>For the purposes of this article, we won't be dealing with different
colours of text or other attributes, so all that's required is to initialise
the Colour Memory: setting all the bytes to reflect "grey on black" allows for
a simple monochromatic output.</p>
<h3>Multiplication:</h3>
<p>The 6510 CPU used by the Commodore 64 doesn't have a multiply instruction,
which means we can't simply "multiply by 8" to get a font-data position.
Luckily, we can use a basic property of binary powers to perform the
calculation:</p>
<samp>
 <h3 class="title">Multiplication by binary powers</h3>
 <pre>x * 8 = x * (2 ** 3)
x * 8 = x &lt;&lt; 3</pre>
</samp>
<p>By shifting the value left, we can simulate multiplication. In this case,
however, that's not quite enough. Shifting a value left pushes the left-most
bits off the end of the register, discarding the higher portion of the result:
we need that higher portion, so some more calculation is required:</p>
<samp>
 <h3 class="title">Multiplication by binary powers into a double-width result</h3>
 <pre>x = 01101101b
LOBYTE(x * 8) = 01101101 &lt;&lt; 3
              = [<em>011</em>]01101000
HIBYTE(x * 8) = [<em>011</em>]
              = 01101101 &gt;&gt; (8-3)

LOBYTE(x * 8) = x &lt;&lt; 3
HIBYTE(x * 8) = x &gt;&gt; 5</pre>
</samp>
<p>The above sample demonstrates a more general rule: a 1-byte by 1-byte
multiplication will generate a 2-byte result, both parts of which can be
calculated by appropriate shifting. This rule can be used by the 6510 code
of the implementation.</p>
<h2>The result</h2>
<p>After putting these algorithms into code, something like the following
will be produced:</p>
<figure>
 <img src="/content/img/c64-80x25-result.png" alt="Lorem ipsum">
 <figcaption>Figure 5: Lorem ipsum on the C64</figcaption>
</figure>
<p>In the example above, the additional algorithms for handling newline
characters have been added to the 80x25 display system, allowing the
text to contain line breaks. This is simply a matter of moving the
cursor down to the start of the next line when a newline character is
encountered.</p>
<p>The system does not currently handle scrolling of the text buffer: if
text is to be drawn below line 25, it will not appear on the display.
Scrolling, and other control sequences including character colour,
will be covered in part 2 of this series.</p>
<p><a href="http://oopsilon.com/c64/80x25.s">80x25.s: 6510 assembly source</a><br>
<a href="http://oopsilon.com/c64/ansi.font">ansi.font: Encoded font data</a><br>
<a href="http://oopsilon.com/c64/80x25.prg">80x25.prg: Assembled binary, emulation-ready</a></p>
<p><a href='mailto:tf@oopsilon.com'>Imran Nazar (tf@oopsilon.com)</a>
 ]]></content>
</entry>
<entry>
 <title type="html">The Structure Pattern in PHP</title>
 <link href="https://imrannazar.com/articles/php-struct-pattern" rel="alternate" type="text/html" title="The Structure Pattern in PHP" />
 <id>https://imrannazar.com/articles/php-struct-pattern</id>
 <summary>Reading and manipulating binary files can be troublesome in PHP, primarily because the language doesn&#039;t have a native type to represent structures of encoded data. Using the Structure pattern allows PHP to load and work with these files, by providing a method of decoding the data into a class and performing calculations. Examples are given in this article of the Windows BMP and TrueType file formats.</summary>
 <category term="Articles" />
 <published>Sun, 20 Jul 2008 00:00:00 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Many file formats contain data in a packed manner: a series of values
which encode information, placed into the file one after another. As an
example, TrueType font files encode information about the font represented in
the file, such as the name of the font and how many characters are contained
within the font face. As another example, Windows BMP files encode the
dimensions and formatting of the image within the format.</p>
<h2>The Need: Structures in C/C++</h2>
<p>In most instances, the information in a file is encoded as a series of
structures, grouping related information such that a programming interface
can retrieve them easily. In C and C++, a special type is set aside for
just such a reason: the <code>struct</code>.</p>
<samp>
 <h3>BMP header structure, in C</h3>
 <pre>typedef struct {
    <kbd>unsigned char</kbd> r;         <s>/* Red */</s>
    <kbd>unsigned char</kbd> g;         <s>/* Green */</s>
    <kbd>unsigned char</kbd> b;         <s>/* Blue */</s>
    <kbd>unsigned char</kbd> reserved;
} RGBQUAD;</pre>
</samp>
<p>The above is the C representation of one palette entry in a Windows BMP.
Once this structure has been defined as a type with <code>typedef</code>,
using it is very simple:</p>
<samp>
 <h3>Using a structure, in C</h3>
 <pre>RGBQUAD palette[256];
<kbd>fread</kbd>(palette, <kbd>sizeof</kbd>(RGBQUAD), <var>256</var>, file_handle);
<kbd>printf</kbd>(<var>"Colour #0 is %02X%02X%02X.\n"</var>, palette[<var>0</var>].r, palette[<var>0</var>].g, palette[<var>0</var>].b);</pre>
</samp>
<p>It can be seen above that the data contained within a <code>struct</code>
can be accessed in much the same way as methods can be accessed within a class,
in C++ or any other object-oriented programming language. Indeed, in C++ the
keywords <code>class</code> and <code>struct</code> are equivalent, and mean
much the same thing.</p>
<h2>The Problem: Structures in PHP</h2>
<p>When using languages such as PHP, a problem arises: PHP does not support a
native <code>struct</code> type. Further, since PHP is a loosely-typed
language, it's not possible to read data from an encoded file format directly
into PHP and manipulate it. This can be alleviated by using PHP's <code>class</code>
keyword to build a class containing the structure members:</p>
<samp>
 <h3>A PHP class with structure members</h3>
 <pre><kbd>class</kbd> RGBQUAD
{
    <s>// Byte size of the structure</s>
    <kbd>const</kbd> SIZE = 16;

    <s>// Structure members</s>
    <kbd>public</kbd> $r;
    <kbd>public</kbd> $g;
    <kbd>public</kbd> $b;
    <kbd>public</kbd> $reserved;

    <s>// Initialise members given packed data</s>
    <kbd>public function __construct</kbd>($data)
    {
        <kbd>if</kbd>($data)
	{
            <kbd>list</kbd>($<var>this</var>-&gt;r,
	         $<var>this</var>-&gt;g,
	         $<var>this</var>-&gt;b,
	         $<var>this</var>-&gt;reserved) = <kbd>unpack</kbd>(<var>'v4'</var>, $data);
	}
    }
}</pre>
</samp>
<p>This representation of the structure makes use of the <code>unpack</code>
function, to take a string of binary data and load it into the class members.
This can be used in a similar fashion to the C representation:</p>
<samp>
 <h3>Using a structure, in PHP</h3>
 <pre>$palette = <kbd>array</kbd>();
for($i=<var>0</var>; $i&lt;<var>256</var>; $i++)
    $palette[$i] = <kbd>new</kbd> RGBQUAD(<kbd>fread</kbd>($file_handle, RGBQUAD::SIZE));

<kbd>printf</kbd>(<var>"Colour #0 is %02X%02X%02X.\n"</var>, $palette[<var>0</var>]-&gt;r, $palette[<var>0</var>]-&gt;g, $palette[<var>0</var>]-&gt;b);</pre>
</samp>
<p>This approach has distinct advantages over the C <code>struct</code> type.
In particular, the PHP implementation is a class, and can contain methods
other than the simple constructor; furthermore, complex types can be contained
within the structure in a way that C cannot accomplish.</p>
<h2>Advanced Usage: TrueType File Format</h2>
<p>An example of complex usage of the structure pattern is in parsing of the
TrueType file format. A TrueType file defines a vector or bitmap font face,
and contains a series of data tables: a table of names, a table of
Windows-specific font information, and tables of glyph definitions. Also
contained in the file structure is a header defining the table "directory",
which allows a parser to find these tables within the file.</p>
<p>A TrueType file begins with information about the version of the TrueType
specification, followed by the table directory. This can be represented in 
PHP in a simple manner:</p>
<samp>
 <h3>TrueType file header and table directory, in PHP</h3>
 <pre><s>// File header. This contains the number of tables in the TTF.</s>
<kbd>class</kbd> ttfHeader
{
  <kbd>const</kbd> SIZE = <var>12</var>;

  <kbd>public</kbd> $majorVersion;
  <kbd>public</kbd> $minorVersion;
  <kbd>public</kbd> $tableCount;
  <kbd>public</kbd> $searchRange;
  <kbd>public</kbd> $entrySelector;
  <kbd>public</kbd> $rangeShift;

  <kbd>public</kbd> $tableDirectory;

  <kbd>public function __construct</kbd>($file)
  {
    $this-&gt;tableDirectory = array();
    
    $header = fread($file, self::SIZE);

    <kbd>list</kbd>($t,
         $this-&gt;majorVersion,
         $this-&gt;minorVersion,
         $this-&gt;tableCount,
         $this-&gt;searchRange,
         $this-&gt;entrySelector,
         $this-&gt;rangeShift) = <kbd>unpack</kbd>(<var>'n*'</var>, $header);

    <kbd>for</kbd>($i=<var>0</var>; $i&lt;$this-&gt;tableCount; $i++)
    {
      $this-&gt;tableDirectory[$i] =
        new ttfTableDirectoryEntry(fread($file, ttfTableDirectoryEntry::SIZE));
    }
  }
}

<s>// Table directory. Describes the location and size of a tables in the TTF.</s>
<kbd>class</kbd> ttfTableDirectoryEntry
{
  <kbd>const</kbd> SIZE = <var>16</var>;

  <kbd>public</kbd> $tag;
  <kbd>public</kbd> $checksum;
  <kbd>public</kbd> $offset;
  <kbd>public</kbd> $length;

  <kbd>public function __construct</kbd>($data)
  {
    <kbd>list</kbd>($t,
         $tag,
         $this-&gt;checksum,
         $this-&gt;offset,
         $this-&gt;length) = <kbd>unpack</kbd>('N*', $data);

    <s>// Build a string tag from the numeric value</s>
    $this-&gt;tag = <kbd>chr</kbd>(($tag&gt;&gt;<var>24</var>)&amp;<var>255</var>).
                 <kbd>chr</kbd>(($tag&gt;&gt;<var>16</var>)&amp;<var>255</var>).
                 <kbd>chr</kbd>(($tag&gt;&gt; <var>8</var>)&amp;<var>255</var>).
                 <kbd>chr</kbd>(($tag&gt;&gt; <var>0</var>)&amp;<var>255</var>);
  }
}</pre>
</samp>
<p>This example shows how it's possible for a structure to contain more
information than the sum of its members. In the case of the
<code>ttfHeader</code>, the constructor can pull in the structure of an
entry in the table directory, and build its own array to represent the
directory.
<p>All in all, the Structure pattern makes it possible for PHP to represent
structures in a similar fashion to C <code>struct</code>s; it also allows
PHP to be more versatile, and represent more complex information related to
the data, which would normally have to be held outside the structure.</p>
<p><em>&copy; Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Intranet DNS Resolution with BIND Views</title>
 <link href="https://imrannazar.com/articles/intranet-dns-with-bind-views" rel="alternate" type="text/html" title="Intranet DNS Resolution with BIND Views" />
 <id>https://imrannazar.com/articles/intranet-dns-with-bind-views</id>
 <summary>When you&#039;re working on a web site that&#039;s hosted in the same office, it can be a problem to see the fruits of your labour: the web site&#039;s domain resolves to the external IP of the office, and can&#039;t be routed from inside. It&#039;s quite easy to overcome this problem, by using the &#039;view&#039; facility of BIND to provide two different views of the domain: one for the office LAN, and one for the outside world.</summary>
 <category term="Articles" />
 <published>Mon, 02 Jun 2008 12:01:48 +0000</published>
 <content type="text/html"><![CDATA[
   <p>From time to time, I write an article for the Oopsilon web site. While the
article is being written, I like to check that it's displaying correctly on
the web site, which involves loading it up in a browser. This is perfectly
fine, except that my working computer is on the same network as the web server,
and the network is internal.</p>
<p>Anyone coming from outside the network (outside my house, in other words)
will be able to view the article without a problem: a request is made to
Oopsilon, which resolves (currently) to <code>87.194.101.173</code>, and a
connection request is made to that IP address. My firewall translates that to
the web server's internal IP of <code>192.168.0.1</code>, and maintains the
translation both ways.</p>
<p>From inside the network, it's another story. Oopsilon resolves to
<code>87.194.101.173</code> as before, but when the firewall receives that
connection request, it sees a connection from the internal network to
the outside world, and immediately back into the network. As a result, the
firewall refuses to connect the request, and I end up unable to see my
article.</p>
<h2>Standard BIND Configuration</h2>
<p>The problem inside the network is caused by Oopsilon resolving to an
external IP. This happens because BIND is configured with a simple DNS
zone, as follows:</p>
<samp>
 <h3>oopsilon.zone: External zone file</h3>
 <pre>IN      SOA     adhocbox.oopsilon.com. tf.oopsilon.com.  (
                                      2008042701 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      604800     ; Expire
                                      86400 )    ; Minimum

                        NS      adhocbox.oopsilon.com.
                        MX 10   oopsilon.com.

oopsilon.com.   IN      A       87.194.101.173
adhocbox        IN      CNAME   oopsilon.com.
www             IN      CNAME   oopsilon.com.</pre>
</samp>
<p>BIND is then told to use this zone for requests relating to the domain in
question, as follows:</p>
<samp>
 <h3>named.conf: BIND master configuration</h3>
 <pre>zone "oopsilon.com" IN {
        type master;
        file "oopsilon.zone";
        allow-update { 88.192.91.15; };
        notify yes;
};</pre>
</samp>
<p>The configuration above states that any requests for the domain will be
serviced by the zone file given. This includes requests from inside the LAN,
which should resolve to the LAN address of the web server. This can be fixed
by using not one, but two zone files.</p>
<h2>View-Specific BIND Configuration</h2>
<p>For external requests, the zone file above is sufficient: serving the
external IP is what these clients will expect. For internal requests, a
seperate zone can be used:</p>
<samp>
 <h3>oopsilon.zone.int: Internal zone file</h3>
 <pre>IN      SOA     adhocbox.oopsilon.com. tf.oopsilon.com.  (
                                      2008042701 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      604800     ; Expire
                                      86400 )    ; Minimum

                        NS      adhocbox.oopsilon.com.
                        MX 10   oopsilon.com.

oopsilon.com.   IN      A       192.168.0.1
adhocbox        IN      CNAME   oopsilon.com.
www             IN      CNAME   oopsilon.com.</pre>
</samp>
<p>In order to select between the two zone files, a series of "views" can be
set up in the configuration file, where each view is matched against a series
of IP addresses. This is done by nesting zones inside view blocks:</p>
<samp>
 <h3>named.conf: Master configuration with views</h3>
 <pre>view "internal" {
        match-clients { 192.168.0.0/24; };
        zone "oopsilon.com" IN {
                type master;
                file "oopsilon.zone.int";
                allow-update { none; };
                notify no;
        };
};

view "external" {
        match-clients { any; };
        zone "oopsilon.com" IN {
                type master;
                file "oopsilon.zone";
                allow-update { 88.192.91.15; };
                notify yes;
        };
};</pre>
</samp>
<p>In the above configuration, there are two views: <code>internal</code> for
clients from the internal network (<code>192.168.0.x</code>), and
<code>external</code> for everyone else. A view can have any number of zones
inside, but in this case I only need one zone in each.</p>
<p>One this configuration has been put in place, its operation is automatic:
anyone from the LAN will receive the LAN IP of the web server, and will be
able to view the web site. Clients outside the network will receive an external
IP, and also be able to see the web site. Everyone wins.</p>
<p><em>Copyright Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">An Introduction to Compression</title>
 <link href="https://imrannazar.com/articles/intro-to-compression" rel="alternate" type="text/html" title="An Introduction to Compression" />
 <id>https://imrannazar.com/articles/intro-to-compression</id>
 <summary>An exploration of the different types of compression, looking at the workings of lossless compression methods such as RLE and Huffman encoding, and taking an overview of perceptive compression and why it works. If you&#039;ve ever wondered how a CD can be shrunk down from 650MB of sound to 65MB, this article tells you how it&#039;s done.</summary>
 <category term="Articles" />
 <published>Thu, 22 May 2008 21:24:30 +0000</published>
 <content type="text/html"><![CDATA[
   <p>I got to thinking recently, about the difference between the GIF and JPEG
image formats: why is it that some images are larger on disk when saved as GIF,
while others are larger as JPEG? It turns out that the different image formats
use different methods of compression.</p>
<p>Compression is simply the name for a set of procedures, that allow data to
be packed into a smaller space, and yet allow the data to be retrieved from the
compressed encoding. It's a two-way process: an input file can yield compressed
output, but putting the compressed output back into the algorithm should give
you a copy of the input.</p>
<h2>Redundancy: Run-Length Encoding</h2>
<p>The concept that makes compression possible is redundancy: the fact that
most data repeats itself in some fashion. A document may use the same word many
times, for example, or a picture will contain the same colour in many places.
A very simple example of a redundant piece of data could be something like the
following.</p>
<samp>
 <h3>Redundancy: Before compression</h3>
 <pre>AAAAABBWWWWWWWWWPPPPQZMMMMVVV</pre>
</samp>
<p>In this case, the redundancy is obvious; repeated series of letters present
themselves throughout the sample. An easy way to compress this would be to
represent the repeated letters by the number of repeats, thus cutting down
on the total length of the sample.</p>
<samp>
 <h3>Redundancy: After compression</h3>
 <pre>A5B2W9P4Q1Z1M4V3</pre>
</samp>
<p>An algorithm reading this encoded version of the sample will be able to
perfectly retrieve the original data: "A" five times, "B" twice, and so on.
This simple algorithm is used extensively, and is called run-length encoding
(RLE): writing down how long each run of characters is. An example of a widely
used standard employing RLE is the venerable PCX image format.</p>
<figure>
 <img src="/content/img/compression-stripes.png" alt="RLE: Stripes">
 <figcaption>Figure 1: Stripes (<a href="http://www.thisisnotparis.com/">Gottschal</a>/<a href="http://www.gluecksbazillus.de/">Schuster</a>)</figcaption>
</figure>
<p>In Figure 1, there are many solid blocks of single colours. This image is
500 pixels wide, and 190 high; as a raw bitmap, using one byte to represent
a pixel, this image would constitute 95kB of data. The PCX algorithm calculates
run lengths for each line of pixels in the image, and then saves the run length
for consecutive pixels of the same colour: in this way, the size of the image
is reduced to 52kB.</p>
<h2>Frequency: Huffman Encoding</h2>
<p>One of the major problems with RLE is that it acts on consecutive values of
data: in Figure 1, the RLE algorithm will treat each horizontal line of the
image separately, whereas all the lines are the same as each other. This can be
alleviated by looking at the data in the whole, and building a table of how
often each value occurs in the entire data set.</p>
<p>Huffman encoding is a method of using this "frequency table", which denotes
the frequency of occurrence for each value, and assigning each entry a code.
The most frequent entries are given shorter codes, and rarer entries are
relegated to receiving long codes. In computing, these codes are invariably
binary codes, which can then be combined into bytes for file storage.</p>
<p>Using the example above, a sample Huffman encoding process may run as follows:</p>
<samp>
 <h3>Huffman encoding: Before compression</h3>
 <pre>AAAAABBWWWWWWWWWPPPPQZMMMMVVV</pre>
</samp>
<figure>
 <table>
  <tr><th>Value</th><th>Frequency</th><th>Code</th></tr>
  <tr><td>Q</td><td>1</td><td>000000</td></tr>
  <tr><td>Z</td><td>1</td><td>000001</td></tr>
  <tr><td>B</td><td>2</td><td>00001</td></tr>
  <tr><td>V</td><td>3</td><td>0001</td></tr>
  <tr><td>P</td><td>4</td><td>001</td></tr>
  <tr><td>M</td><td>4</td><td>011</td></tr>
  <tr><td>A</td><td>5</td><td>01</td></tr>
  <tr><td>W</td><td>9</td><td>1</td></tr>
 </table>
 <figcaption>Table 1: Frequency and Huffman table</figcaption>
</figure>
<samp>
 <h3>Huffman encoding: After compression</h3>
 <pre>01 01 01 01 01 00001 00001 1 1 1 1 1 1 1 1 1 001 001 001 001 000000 000001 011 011 011 011 0001 0001 0001
&#x0055;&#x0042;&#x001F;&#x00F9;&#x0024;&#x0080;&#x000B;&#x006D;&#x00B1;&#x0088;</pre>
</samp>
<p>Using Huffman encoding, the data has been whittled down from 29 characters
to 10 bytes. This does not include the frequency and coding table, which has to
be stored with the compressed data for it to make any sense; in this example,
the frequency table is larger than the compressed data, but the size of the
frequency table is negligible in most cases.</p>
<p>It is, of course, possible to combine RLE and Huffman encoding, performing
RLE first and then running the compressed result through the Huffman algorithm.
This produces especially good results on simple images: Figure 1 above can be
compressed from a 95kB bitmap to a 4kB file by using the GIF file format, which
combines RLE, Huffman encoding and other algorithms.</p>
<h2>Perception: Lossy Encoding</h2>
<p>The methods outlined above can be used to compress data in such a manner
that it can be perfectly reproduced. Examples of this usage of compression
include documents and software programs, where the loss or corruption of one
value may render the file worthless.</p>
<p>In certain circumstances, a perfect reproduction of the data in question
is not necessary: a close approximation is sufficient. Generally, these
circumstances arise in multimedia applications: sounds beyond the range of
human hearing need not be recorded, and subtleties of colour and gradient
beyond the discernment of the human eye need not be reproduced.</p>
<p>A classic example of this is the MPEG Audio standard, which attempts to
reduce the size of audio files by removing extraneous information regarding
high-frequency sounds. The Layer-3 specification of this standard allows for
various settings of removal, by which progressively more information will
be removed from the audio sample.</p>
<figure>
 <img src="/content/img/compression-mp3.gif" alt="MP3 compression">
 <figcaption>Figure 2: Yard&#x0131;m Et (<a href="http://www.morveotesi.com/">Mor ve &Ouml;tesi</a>, "D&uuml;nya Yalan S&ouml;yl&uuml;yor")<br>Encoded with MPEG Audio Layer-3</figcaption>
</figure>
<p>In Figure 2 above, two waveforms are superimposed: the original song
waveform in red, and a highly compressed variant overlaid in blue. The sample
shown above is 1.5 seconds long; as a section in the original waveform file,
this sample is stored using 160kB of data. The compressed variant shown is
of the same length, occupying only 48kB of space.</p>
<p>This has been achieved by the MPEG Audio compression algorithm, by
transposing the sound into its frequency components, and removing those
components beyond the range of human hearing (above approximately 20kHz).
By doing this, the resultant waveform is not significantly affected, as can
be seen above, and thus the compressed sound is not perceptibly different from
that of the original source.</p>
<h2>Throwing Data Away: Visual Lossy Encoding</h2>
<p>Just as a sound file has high-frequency components that can't be discerned
by the ear, a picture has high-frequency components: shades of colour that
aren't different enough for the eye to distinguish, or gradients that run from
black to white so quickly that there's no space for the gradient to be seen.
Just as with sound, these components can be removed from a picture; this is the
premise of the JPEG image format.</p>
<p>JPEG performs a variant of the same algorithm used in MPEG Audio, to
retrieve a two-dimensional map of the frequency components contained within
an image; the algorithm then proceeds to cut the components down, and recombine
the image. An example of this process is shown below.</p>
<figure>
 <img src="/content/img/compression-jpeg-sharp.gif" alt="JPEG compression of corners">
 <figcaption>Figure 3: JPEG compression applied to a diagram</figcaption>
</figure>
<p>In Figure 3, an image composed of four 16x16-pixel squares is compared
against the JPEG-encoded variant of the same file. A sharp change in colour
or luminance is defined as an event of high visual frequency, and it is here
where JPEG performs its removal. As a result, the encoded image has a lower
definition to its edges, and the meeting point of the four squares is
especially blurred.</p>
<p>The strength of JPEG is not in encoding images of sharp edges and corners,
but instead in images of low visual frequency; photographs are a prime
example of such.</p>
<figure>
 <img src="/content/img/compression-jpeg-photo.gif" alt="JPEG compression of photos">
 <figcaption>Figure 4: JPEG compression applied to a photograph</figcaption>
</figure>
<p>In Figure 4, a 300x300 image of Antalya Harbour is encoded by JPEG. The
original bitmap is 270kB, whereas by removal of the sharp edges and colour
changes, JPEG is able to produce a 22kB image. As far as the human eye is
concerned, very little has changed in the image; the features shown in the
image survive intact, even if the pixels have changed somewhat.</p>
<p>This is the main concept behind lossy encoding: that the exact data is
not as important as the information presented by the data. Using the JPEG
algorithm to encode a software program would be unwise, but in cases where
the information is more than the sum of the data, lossy encoding is ideal.</p>
<h2>Perceptive Redundancy: Video Encoding</h2>
<p>When it comes to video clips, it's possible to compress the data involved
yet further, by combining the principles behind lossless and lossy encoding.
The simplest and most naive method of building a video clip is to tack together
consecutive pictures and refer to them as frames: the MJPEG video file format
does this by treating a series of JPEG images as individual frames.</p>
<p>What this approach ignores is the inherent redundancy in a video clip:
most of the information contained in a given frame is also in the previous
frame. Only a small percentage of any particular frame is new information; by
calculating where that percentage of information lies, and storing only that
amount, it's possible to drastically cut down the data size of the frame.</p>
<figure>
 <img src="/content/img/compression-mpeg-diff.gif" alt="MPEG frame differential">
 <figcaption>Figure 5: Consecutive frames of video, and their difference (<a href="http://jpl.nasa.gov/">NASA JPL</a>)</figcaption>
</figure>
<p>In Figure 5, the second frame of video shows very little change relative
to the first: only in the Shuttle's exhaust plume is there significant
motion. Indeed, the output of the <acronym title="Solid Rocket Booster">SRB</acronym>s
and the sky behind the launch tower are entirely unchanged between frames.
Instead of storing these portions of the image in their entirety, it's
possible to store a single value: "No change".</p>
<p>The MPEG Video standard makes use of this inherent redundancy as a part of
its compression algorithm. In theory, only the initial frame of a shot is
required in full: any movement as part of the shot can be stored as a 
difference from the previous frame. The initial frame, known as an Intra-frame,
is stored as a standard JPEG image, and the subsquent difference frames are
called inter-frames, or Predicted frames.</p>
<p>In practice, the MPEG Video standard was designed with "streaming" in mind:
the ability to begin viewing a video clip halfway through a shot. If only one
Intra-frame (I-frame) is provided for the shot, it's not possible for the
Predicted frames (P-frames) to interpolate their differences. For this reason,
I-frames are commonly inserted at regular intervals into the video clip,
regardless of whether a shot is in progress.</p>
<figure class="invertable">
 <img src="/content/img/compression-mpeg-graph.gif" alt="MPEG frame size graph">
 <figcaption>Figure 6: Frame sizes for a 4-second MPEG clip (<a href="http://news.bbc.co.uk/">BBC News</a>)</figcaption>
</figure>
<p>In Figure 6 above, the video clip has I-frames inserted at 25-frame
intervals, or once a second. The subsequent P-frames are each much smaller
in size than the I-frame, since politicians tend not to move around very
much when interviewed, thus causing a lower amount of difference between
frames.</p>
<p>The example used for Figure 6 was a 400x224 video clip of 4 seconds. In
raw bitmap form, the size of the resultant file would be 26.7MB; by using
the combined techniques of lossy encoding and redundancy, the MPEG Video
standard is able to reduce this to 300kB, a reduction of 99%.</p>
<h2>Conclusion: Where To Go Lossy</h2>
<p>The examples of lossy encoding presented in this article are employed in
special circumstances: audio, video, pictures. It's only in these instances,
and others related to these, that perception is the important factor in
the compression process. For other compression targets, such as documents and
software programs, it's important to preserve the data exactly as-is.</p>
<p>More advanced specialisations of compression are being developed all the
time, but most common implementations of compression are based on the
techniques in this article: eliminating redundant and duplicate information.
Compression works best when there's a lot of redundant data, so don't try to
compress a compressed file.</p>
<p><em>Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Whitelisting SSH Access with OpenWRT</title>
 <link href="https://imrannazar.com/articles/ssh-whitelist-with-openwrt" rel="alternate" type="text/html" title="Whitelisting SSH Access with OpenWRT" />
 <id>https://imrannazar.com/articles/ssh-whitelist-with-openwrt</id>
 <summary>If you&#039;re tired of constant login attacks against your SSH server, you can use your OpenWRT router to implement a whitelisting firewall, allowing the people you know and trust to connect to your shell, and blocking everything else. It&#039;s even possible to automatically modify the whitelist from an intranet Web page, through the use of extensions to PHP; this article will show you how it&#039;s done.</summary>
 <category term="Articles" />
 <published>Fri, 09 May 2008 18:29:17 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Sometimes, I take the liberty of looking through the log files of my
server. Invariably, there's something like the following at the bottom:</p>
<samp>
 <h3>Sample SSH log file</h3>
 <pre>May  8 01:46:43 adhocbox sshd[28514]: Invalid user tanta from 61.100.x.x
May  8 01:46:46 adhocbox sshd[28516]: Invalid user cornel from 61.100.x.x
May  8 01:46:49 adhocbox sshd[28518]: Invalid user ronaldo from 61.100.x.x
May  8 01:46:51 adhocbox sshd[28520]: Invalid user wave from 61.100.x.x
May  8 01:46:54 adhocbox sshd[28522]: Invalid user vanilla from 61.100.x.x
May  8 01:46:57 adhocbox sshd[28524]: Invalid user ice from 61.100.x.x
May  8 01:47:02 adhocbox sshd[28526]: Invalid user mason from 61.100.x.x</pre>
</samp>
<p>This is repeated for a few hundred lines, and is followed a few hours
later by another batch of attacks from another IP. It gets tiresome for one's
bandwidth to be taken up by these attempts at logins, especially when the
server only has one valid user, as is the case for my setup.</p>
<p>I decided to put an end to this, by implementing a whitelist: allowing
specific IPs through at the firewall, and blocking all others. Fortunately,
I run an OpenWRT installation on my Internet router, which provides Linux's
<code>iptables</code> infrastructure for the manipulation of firewall rules.
In this article, I'll detail how I set up my whitelist system, and how you
can do the same.</p>
<h2>What you'll need</h2>
<p>My network consists of a Linksys WRT54G wireless router hosting the
firewall, and a webserver running a distribution of Linux. For the purposes
of this setup, the particulars of the webserver aren't an issue, but you
will need:</p>
<dl>
 <dt>OpenWRT:</dt>
 <dd>My Linksys router has been reflashed with OpenWRT Whiterussian, which
 provides the <code>iptables</code> firewall, along with simplification
 scripts for the firewall rules. Any Linux box can act as the firewall,
 as long as you can pull the appropriate formatting together for the rules.</dd>
 <dt>PHP with PECL-SSH2:</dt>
 <dd>OpenWRT provides SSH access to the router, which allows for direct
 editing of the firewall configuration file. We'll be using this to our
 advantage, by programmatically adding IPs to the whitelist using PHP.</dd>
 <dt>An external computer:</dt>
 <dd>The easiest way to test the whitelist setup is by using a computer
 that's outside the LAN; this will allow you to check that packets are
 being appropriately blocked at the router, which will not necessarily be
 the case if you're going between computers inside the LAN.</dd>
</dl>
<h2>The OpenWRT Firewall</h2>
<p>OpenWRT provides a simple wrapper over the Linux <code>iptables</code>
interface, using <code>awk</code> to rewrite the contents of a configuration
file into filtering and NAT rules, which are then applied by an init script.
There's also a wrapper on top of that, which constitutes the Web interface
to the firewall; it is this interface that most people associate with the
OpenWRT firewall.</p>
<p>The major issues with the Web interface are that it's relatively clunky,
especially when it comes to changing the order of firewall rules; new rules
are added to the bottom of the list, and moving them to the top involves an
arduous series of clicks and page loads. For most purposes, direct editing of
the configuration file makes more sense.</p>
<p>A simple configuration may contain among its rules the following:</p>
<samp>
 <h3>OpenWRT's /etc/config/firewall: A sample</h3>
 <pre>accept:dport=113 src=192.168.0.0/24
forward:proto=tcp dport=22:192.168.0.1:22
forward:proto=tcp dport=80:192.168.0.1:80
drop</pre>
</samp>
<p>This sample script will allow the firewall to <code>accept</code> Ident
requests from inside the LAN, <code>forward</code> SSH and HTTP to a server
at 192.168.0.1, and <code>drop</code> everything else. The parameters to each
rule are parsed out by the init script, and built into <code>iptables</code>
rules.</p>
<p>Just as with <code>iptables</code>, these rules are processed in order,
and the first rule to match the incoming packet is applied. By using this
principle, it's simple to put together a ruleset which will act as a
whitelist for SSH:</p>
<samp>
 <h3>Whitelisting SSH: firewall ruleset</h3>
 <pre>forward:proto=tcp src=[IP #1] dport=22:192.168.0.1:22
forward:proto=tcp src=[IP #2] dport=22:192.168.0.1:22
drop:proto=tcp dport=22</pre>
</samp>
<p>In this example, any SSH packets coming from specific
external IPs will be forwarded to the SSH server, and any other SSH
packets will be dropped at the firewall. This is the behaviour which allows
a whitelist: the next problem is how to add IPs to the list.</p>
<h2>Adding IPs to the Whitelist</h2>
<p>There are two ways to add addresses to this firewall ruleset. The first
is to SSH into the OpenWRT router, edit the configuration file to add the
appropriate rule, and then restarting the firewall service:</p>
<samp>
 <h3>Manually updating the whitelist</h3>
 <pre>ssh -l root 192.168.0.254
vim /etc/config/firewall
/etc/init.d/S45firewall restart</pre>
</samp>
<p>The problems with this method are two-fold:</p>
<dl>
 <dt>Ease of use:</dt>
 <dd>This manual method of updating the list doesn't constitute the most
 user-friendly interface to addition of IPs, and it can get tiresome to
 add IPs months or years after the whitelist is initially put into place.</dd>
 <dt>Access:</dt>
 <dd>Almost exclusively, access to the router's SSH port is only available
 from inside the LAN. From an external viewpoint, this availability will only
 exist by connecting from the accessible SSH server residing on the LAN. This
 in turn is governed by the whitelist, held on the router. The eponymous
 Catch-22 situation is an apt description of this problem.</dd>
</dl>
<p>Instead of using a manual process to update the list, it's possible to
provide an externally-accessible interface to add IPs. In my case, I have
a Web server (which happens to be my SSH server), so I can use a Web script
to provide this interface; for the purposes of this article, PHP has been used
as the language doing the work.</p>
<p>PHP doesn't have an interface to SSH version 2 by default: this is
provided by a PECL extension named <code>ssh2</code>. Once this has been
put in place, a variety of methods are exposed to allow for SSH connections
to be made. These can be used to perform work on the OpenWRT router:</p>
<samp>
 <h3>Use PECL_ssh2 to connect to the router</h3>
 <pre>$ssh = <kbd>ssh2_connect</kbd>(<var>'192.168.0.254'</var>);
if(<kbd>ssh2_auth_password</kbd>($ssh, <var>'root'</var>, <var>'[router root passwd]'</var>))
{
	$stream = <kbd>ssh2_shell</kbd>($ssh);
	<kbd>fwrite</kbd>($stream, <var>'touch /tmp/newfile'</var>);
}</pre>
</samp>
<p>As an aside, if you don't like having the router's root password lying
around in a PHP file, the PECL ssh2 extension also provides a public key
authentication mechanism, and the SSH server on an OpenWRT installation
allows addition of public keys in the same manner as OpenSSH.</p>
<h2>Using PHP to automatically add IPs</h2>
<p>Opening an interactive shell with <code>ssh2_shell</code> allows more
than one command to be executed, which means we can do the file
manipulation required to add an address to the list. We can combine
everything, to produce the following script.</p>
<samp>
 <h3>ssh.php: Add an IP to the router's whitelist</h3>
 <pre><kbd>&lt;?php</kbd>
if(<kbd>isset</kbd>($_POST[<var>'add'</var>])):
	$ssh = <kbd>ssh2_connect</kbd>(<var>'192.168.0.254'</var>);
	if(<kbd>ssh2_auth_password</kbd>($ssh, <var>'root'</var>, <var>'[router root passwd]'</var>))
	{
		$fp = <kbd>ssh2_shell</kbd>($ssh);
		<kbd>fwrite</kbd>($fp, <var>'echo "forward:proto=tcp src='</var>.$_POST[<var>'ip'</var>].<var>' dport=22:192.168.0.1:22" &gt; /tmp/1'</var>.<var>"\n"</var>);
		<kbd>fwrite</kbd>($fp, <var>"cp /etc/config/firewall /tmp/2\n"</var>);
		<kbd>fwrite</kbd>($fp, <var>"cat /tmp/1 /tmp/2 &gt; /etc/config/firewall\n"</var>);
		<kbd>fwrite</kbd>($fp, <var>"/bin/sh /etc/init.d/S45firewall\n"</var>);

		<s>// Provide enough time for the firewall to restart</s>
		<kbd>sleep</kbd>(<var>10</var>);
	}
	<kbd>echo</kbd> <var>"Done."</var>;
else:
<kbd>?&gt;</kbd>
<s>&lt;form method="post"&gt;
 &lt;input type="text" name="ip"&gt;
 &lt;input type="submit" name="add" value="Add"&gt;
&lt;/form&gt;</s>
<kbd>&lt;?php</kbd>
endif;
<kbd>?&gt;</kbd></pre>
</samp>
<p>All that's required now is to navigate to this script, put an IP into
the box, and wait 10 seconds. When this process has completed, the IP has
automatically been added to the top of the firewall script, and the
firewall restarted.</p>
<p>That should be everything you need to set up your own whitelist access
list for SSH. No more brute-force attacks against your server!</p>
<p><em>Copyright Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2008</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">Making PDO Look Like ADODB</title>
 <link href="https://imrannazar.com/hacks/adodb-pdo" rel="alternate" type="text/html" title="Making PDO Look Like ADODB" />
 <id>https://imrannazar.com/hacks/adodb-pdo</id>
 <summary>Many developers who come to PHP from ASP bring their experience of using ActiveX Data Objects (ADO) to interface with databases; however, existing solutions to allow ADO usage from PHP suffer from performance and support issues. Using PHP&#039;s native Data Objects (PDO) library can be infeasible for legacy applications: with the code provided here, PDO can be used with no redevelopment of the application.</summary>
 <category term="Quick Hacks" />
 <published>Mon, 21 Apr 2008 20:56:38 +0000</published>
 <content type="text/html"><![CDATA[
     <p>Many developers who come to PHP from the Visual Basic set of languages
  wish to take their experience of database interfacing with them. In the VB
  world, ActiveX Data Objects (ADO) is used to interact with a database; since
  PHP has no native library for ADO, this can present a problem.</p>
  <p>With this in mind, an ADO library was written for use by PHP developers
  many years ago, which would allow developers to directly port their existing
  code and interfaces to PHP. There are a few problems with this approach, as
  can be expected:</p>
  <ul>
   <li>The ADO library is written in PHP, and because it was written some time
   ago, the language used within the library is specific to PHP 4. Since this
   version of PHP has reached the end of its support lifecycle, it's highly
   unlikely that any issues that arise with the ADO interface will be fixed.</li>
   <li>Further, because the library is written in PHP, it's incredibly slow
   to load and execute, introducing multiple additional layers between the
   PHP business logic layer and the database.</li>
  </ul>
  <p>With the advent of PHP 5, a native database access layer was introduced
  to the core language: PHP Data Objects (PDO). Since this layer interfaces
  directly with the PHP core, it can operate on a much more efficient level,
  and therefore loads and runs much more quickly. Furthermore, since it's a
  current extension to PHP, it is maintained and kept secure.</p>
  <p>In the ideal case, any applications using ADO under PHP would be
  redeveloped to use PDO. For large applications, however, this is infeasible:
  some kind of layer must be introduced over PDO, to "fake" the functionality
  of ADO on behalf of the application. The following is just such a layer.</p>
  <samp>
   <h3>ADODB-PDO.php: PDO wrapper to provide an ADODB interface</h3>
   <pre>
define(<var>'ADODB_FETCH_NUM'</var>, <var>PDO::FETCH_NUM</var>);
define(<var>'ADODB_FETCH_ASSOC'</var>, <var>PDO::FETCH_ASSOC</var>);

<s>/**
* Connection and query wrapper
*/</s>
class ADODB_PDO
{
    <s>/** PDO connection to wrap */</s>
    private $_db;
    
    <s>/** Connection information (database name is public) */</s>
    private $connector;
    private $dsn;
    private $host;
    private $user;
    private $pass;
    public $database;
    
    <s>/** Debug flag, publically accessible */</s>
    public $debug;
    
    <s>/** PDO demands fetchmodes on each resultset, so define a default */</s>
    private $fetchmode;

    <s>/** Number of rows affected by the last Execute */</s>
    private $affected_rows;
    
    <s>/**
    * Constructor: Initialise connector
    * @param connector String denoting type of database
    */</s>
    public function __construct($connector=<var>'mysql'</var>)
    {
        $this-&gt;connector = $connector;
    }
    
    <s>/**
    * Connect: Establish connection to a database
    * @param host String
    * @param user String [optional]
    * @param pass String [optional]
    * @param database String [optional]
    */</s>
    public function Connect($host, $user=<var>''</var>, $pass=<var>''</var>, $database=<var>''</var>)
    {
        $this-&gt;host = $host;
        $this-&gt;user = $user;
        $this-&gt;pass = $pass;
        $this-&gt;database = $database;

        switch($this-&gt;connector)
        {
            case 'mysql':
                $this-&gt;dsn = sprintf(<var>'%s:host=%s;dbname=%s'</var>,
                    $this-&gt;connector,
                    $this-&gt;host,
                    $this-&gt;database);
                $this-&gt;_db = new PDO($this-&gt;dsn, $this-&gt;user, $this-&gt;pass);
                $this-&gt;_db-&gt;setAttribute(<var>PDO::MYSQL_ATTR_USE_BUFFERED_QUERY</var>, <kbd>true</kbd>);
                $this-&gt;fetchmode = ADODB_FETCH_ASSOC;
                break;
        }
    }

    <s>/**
    * SetFetchMode: Change the fetch mode of future resultsets
    * @param fm Integer specified by constant
    */</s>
    public function SetFetchMode($fm)
    {
        $this-&gt;fetchmode = $fm;
    }

    <s>/**
    * Insert_ID: Retrieve the ID of the last insert operation
    * @return String containing last insert ID
    */</s>
    public function Insert_ID()
    {
        return $this-&gt;_db-&gt;lastInsertId();
    }

    <s>/**
    * GetAll: Retrieve an array of results from a query
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return Array of results
    */</s>
    public function GetAll($sql, $vars=<kbd>null</kbd>)
    {
        $st = $this-&gt;DoQuery($sql, $vars);
        return $st?$st-&gt;fetchAll():false;
    }

    <s>/**
    * CacheGetAll: Wrapper to emulate cached GetAll
    * @param timeout int count of seconds for cache expiry
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return Array of results
    */</s>
    public function CacheGetAll($timeout, $sql, $vars=<kbd>null</kbd>)
    {
        return $this-&gt;GetAll($sql, $vars);
    }

    <s>/**
    * Execute: Retrieve a resultset from a query
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return ADODB_PDO_ResultSet object
    */</s>
    public function Execute($sql, $vars=<kbd>null</kbd>)
    {
        $st = $this-&gt;DoQuery($sql, $vars);
        $this-&gt;affected_rows = $st-&gt;rowCount();
        return $st?new ADODB_PDO_ResultSet($st):false;
    }

    <s>/**
    * CacheExecute: Wrapper to emulate cached Execute
    * @param timeout int count of seconds for cache expiry
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return ADODB_PDO_ResultSet object
    */</s>
    public function CacheExecute($timeout, $sql, $vars=<kbd>null</kbd>)
    {
        return $this-&gt;Execute($sql, $vars);
    }

    <s>/**
    * Affected_Rows: Retrieve the number of rows affected by Execute
    * @return The number of affected rows
    */</s>
    public function Affected_Rows()
    {
        return $this-&gt;affected_rows;
    }

    <s>/**
    * GetRow: Retrieve the first row of a query result
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return Array of data from first result
    */</s>
    public function GetRow($sql, $vars=<kbd>null</kbd>)
    {
        $st = $this-&gt;DoQuery($sql, $vars);
        return $st?$st-&gt;fetch():false;
    }

    <s>/**
    * GetOne: Retrieve the first value in the first row of a query
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return String data of the requested value
    */</s>
    public function GetOne($sql, $vars=<kbd>null</kbd>)
    {
        $st = $this-&gt;DoQuery($sql, $vars);
        return $st?$st-&gt;fetchColumn():false;
    }

    <s>/**
    * GetAssoc: Retrieve data from a query mapped by value of first column
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return Array of mapped data
    */</s>
    public function GetAssoc($sql, $vars=<kbd>null</kbd>)
    {
        $out = array();
        $st = $this-&gt;DoQuery($sql, $vars);

        if($st)
        {
            if($st-&gt;columnCount() &gt; <var>2</var>)
            {
                while($row = $st-&gt;fetch())
                {
                    $rowidx = array_shift($row);
                    $out[$rowidx] = $row;
                }
            }
            else if($st-&gt;columnCount == <var>2</var>)
            {
                while($row = $st-&gt;fetch())
                {
                    $rowidx = array_shift($row);
                    $out[$rowidx] = array_shift($row);
                }
            }
            else $out = false;
        }
        else $out = false;
        return $out;
    }

    <s>/**
    * GetCol: Retrieve the values of the first column of a query
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return Array of column data
    */</s>
    public function GetCol($sql, $vars=<kbd>null</kbd>)
    {
        $out = array();
        $st = $this-&gt;DoQuery($sql, $vars);

        if($st)
        {
            while($val = $st-&gt;fetchColumn()) $out[] = $val;
            return $out;
        }
        else return false;
    }

    <s>/**
    * MetaColumns: Retrieve information about a table's columns
    * @param table String name of table to find out about
    * @return Array of ADODB_PDO_FieldData objects
    */</s>
    public function MetaColumns($table)
    {
        $out = array();
        
        $st = $this-&gt;DoQuery('select * from '.$table);
        for($i=<var>0</var>; $i&lt;$st-&gt;columnCount(); $i++)
            $out[] = new ADODB_PDO_FieldData($st-&gt;getColumnMeta($i));

        return $out;
    }

    <s>/**
    * qstr: Quote a string for use in database queries
    * @param in String parameter to quote
    * @return String quoted by database
    */</s>
    public function qstr($in)
    {
        return $this-&gt;_db-&gt;quote($in);
    }
    
    <s>/**
    * quote: Quote a string for use in database queries
    * @param in String parameter to quote
    * @return String quoted by database
    */</s>
    public function quote($in)
    {
        return $this-&gt;_db-&gt;quote($in);
    }
    
    <s>/**
    * DoQuery: Private helper function for Get*
    * @param sql String query to execute
    * @param vars Array of variables to bind [optional]
    * @return PDOStatement object of results, or false on fail
    */</s>
    private function DoQuery($sql, $vars=<kbd>null</kbd>)
    {
        $st = $this-&gt;_db-&gt;prepare($sql);
        $st-&gt;setFetchMode($this-&gt;fetchmode);
        if(!is_array($vars)) $vars = array($vars);
        return $st-&gt;execute($vars)?$st:false;
    }
}

<s>/**
* Resultset wrapper
*/</s>
class ADODB_PDO_ResultSet
{
    <s>/** PDO resultset to wrap */</s>
    private $_st;
    
    <s>/** One-time resultset information */</s>
    private $results;
    private $rowcount;
    private $cursor;

    <s>/** Publically accessible row values */</s>
    public $fields;

    <s>/** Public end-of-resultset flag */</s>
    public $EOF;

    <s>/**
    * Constructor: Initialise resultset and first results
    * @param st PDOStatement object to wrap
    */</s>
    public function __construct($st)
    {
        $this-&gt;_st = $st;
        $this-&gt;results = $st-&gt;fetchAll();
        $this-&gt;rowcount = count($this-&gt;results);
        $this-&gt;cursor = <var>0</var>;
        $this-&gt;MoveNext();
    }

    <s>/**
    * RecordCount: Retrieve number of records in this RS
    * @return Integer number of records
    */</s>
    public function RecordCount()
    {
        return $this-&gt;rowcount;
    }

    <s>/**
    * MoveNext: Fetch next row and check if we're at the end
    */</s>
    public function MoveNext()
    {
        $this-&gt;fields = $this-&gt;results[$this-&gt;cursor++];
        $this-&gt;EOF = ($this-&gt;cursor == $this-&gt;rowcount) ? <var>1</var> : <var>0</var>;
    }
}

<s>/**
* Table field information wrapper
*/</s>
class ADODB_PDO_FieldData
{
    public $name;
    public $max_length;
    public $type;
    
    <s>/**
    * Constructor: Map PDO meta information to object field data
    * @param meta Array from PDOStatement::getColumnMeta
    */</s>
    public function __construct($meta)
    {
        $lut = array(
            <var>'LONG'</var> =&gt; <var>'int'</var>,
            <var>'VAR_STRING'</var> =&gt; <var>'varchar'</var>
        );
        
        $this-&gt;name = $meta[<var>'name'</var>];
        $this-&gt;max_length = $meta[<var>'len'</var>];
        $this-&gt;type = $lut[$meta[<var>'native_type'</var>]];
    }
}

<s>/**
* NewADOConnection: Thin wrapper to generate a new ADODB_PDO object
* @param connector String denoting type of database
* @return ADODB_PDO object
*/</s>
function NewADOConnection($connector)
{
    return new ADODB_PDO($connector);
}
   </pre>
  </samp>
 ]]></content>
</entry>
<entry>
 <title type="html">Booting Linux from a USB Flash Drive</title>
 <link href="https://imrannazar.com/articles/linux-flash-boot" rel="alternate" type="text/html" title="Booting Linux from a USB Flash Drive" />
 <id>https://imrannazar.com/articles/linux-flash-boot</id>
 <summary>For those who build home theatre PCs and other computers which need to be quiet in operation, most of the noise from computer hardware can be eliminated: fans can be removed, heatsinks and smaller power supplies can be used. The largest remaining source of noise is the hard disk containing the operating system. If the HTPC is running Linux, it&#039;s possible to move that operating system from hard disk to a USB flash drive, and boot it from there; this article shows you how.</summary>
 <category term="Articles" />
 <published>Sun, 07 Oct 2007 21:25:47 +0000</published>
 <content type="text/html"><![CDATA[
   <p>I like my computers to be as quiet as possible: if a computer is emitting very little sound, that makes it easier to live with. The noise a computer makes is especially important when it's in a home theatre situation, or acting as a media server; if a <abbr title="Home Theatre PC">HTPC</abbr> is itself throwing out lots of noise, that detracts from the sound of the movie being played.</p>
<p>The ideal case, of course, is for there to be no moving parts: things that move or spin inevitably have friction, and that causes noise. I've tried to eliminate everything that spins from my setup: I have a CPU that doesn't need a fan on the heatsink, and a fanless power supply. However, there's one thing left that is spinning, and that's the hard disk which hosts the Linux installation. Dropping that would make my system truly silent, so I started looking into how that could be done.</p>
<p>The only viable choice for a non-spinning medium to host the operating system is a USB Flash drive: most motherboard BIOSes have the ability to boot from a Flash device, and there's no other medium which is easily available in the sizes required. So the choice was obvious: copy the operating system from hard disk to Flash, and boot it from there.</p>
<p>Unfortunately, it's not quite that easy. In order for the BIOS to understand the Flash disk and boot from it, the disk must be formatted in a very simple format: specifically, good old FAT32. It's quite unacceptable for a Linux root filesystem to be based on FAT32, so a certain process has to be run through:</p>
<ul>
 <li>Compress the root filesystem down into a disk image</li>
 <li>Boot the Linux kernel from a FAT-formatted Flash disk</li>
 <li>Get the kernel to mount the compressed image</li>
 <li>Continue booting from that image</li>
</ul>
<h2>What you'll need</h2>
<p>Each step will require its own tools to get the job done, and I'll be covering the details behind each of these tools when they're used. In the meantime, here's a short list of everything that will be employed:</p>
<dl>
 <dt>SquashFS tools:</dt>
 <dd>We'll be using SquashFS to compress the root filesystem into an image, and the SquashFS make-filesystem tool will be needed for that.</dd>
 <dt>SysLinux:</dt>
 <dd>Getting Linux to boot from a FAT-formatted disk is no mean feat, unless you use SysLinux; it makes everything so much easier.</dd>
 <dt>BusyBox:</dt>
 <dd>In order for Linux to boot the filesystem image, it'll need to <code>mount</code>, <code>cd</code> and <code>pivot_root</code>, among other things. BusyBox provides all these tools in one go, as I'll explain in more detail later.</dd>
</dl>
<h2>Stage 1a: Copying the existing root</h2>
<p>The first step is to build the disk image that will eventually act as the root filesystem. This will most likely come from a system that's already running: in my case, I'll be using the media server, which runs on Gentoo. We can't compress <code>/</code> as-is, since other filesystems are mounted into it, so we have to remove those mounts. A simple way of doing this is to remount <code>/</code> somewhere else, by binding it with <code>mount</code>:</p>
<samp>
 <h3>Bindmounting <code>/</code> to remove mount points</h3>
 <pre># mkdir /root/bindmount
# mount -o bind / /root/bindmount</pre>
</samp>
<p>The new bindmounted root is a plain representation of what's on the disk, with no additional mounts: that means there should be no files in <code>/proc</code> or </code>/sys</code>, and the bare minimum in <code>/dev</code>. If there are any files in these three directories, you can safely get rid of them:</p>
<samp>
 <h3>Cleaning out the mount shadows</h3>
 <pre># cd /root/bindmount
# rm -rf proc/* dev/* sys/*
# cp -a /dev/console /dev/null /dev/initctl dev</pre>
</samp>
<p>The last line above copies over the three devices which are initally needed by the boot process: the character devices for the console and <code>null</code>, and the FIFO used by <code>init</code>. Every other device is filled in by the kernel when <code>udev</code> automatically populates <code>/dev</code>.</p>
<p>We're still operating on the root filesystem itself; it's now safe to make a copy, to which we can make any further changes:</p>
<samp>
 <h3>Copying the bindmount</h3>
 <pre># mkdir /root/fscopy
# cp -av /root/bindmount/* /root/fscopy</pre>
</samp>
<p>Once the copy is complete, any files in the copy's <code>tmp</code> and <code>var/tmp</code> directories can safely be cleaned out, since they're temporaries and won't be needed.</p>
<h2>Stage 1b: Compressing the existing root</h2>
<p>In an ideal world, you'd be able to take the filesystem copy and dump it to Flash, from which it would run. Unfortunately, there are two reasons as to why it's not that simple:</p>
<dl>
 <dt>FAT32:</dt>
 <dd>As I mentioned earlier, the filesystem employed by Flash drives is FAT, which isn't conducive to holding a Linux root filesystem. No problem; we simply hold an uncompressed disk image on the drive and read/write to that. That causes us to run into a second problem;</dd>
 <dt>Write Limits:</dt>
 <dd>Flash memory has a limit on how many times it can be written to before bits start sticking and data gets corrupted. Sure, it's a figure with six zeros, and hard drives have a similar limit, but I don't want this setup to work for a year or two; I'd like it to run for many years yet. Therefore, we need a way to store the filesystem that won't involve writing changes to Flash.</dd>
</dl>
<p>Fortunately, people more clever than I have devised a way of doing this: keep a compressed image on the Flash as a read-only starting point for the filesystem, and hold the changes in a RAM drive. I'll be setting up the RAM drive later, but the disk image can be done right now, using SquashFS.</p>
<p>There are two redeeming factors to SquashFS. Firstly, it has a hugely high compression ratio; the 2GB filesystem on my media server compresses down to about 500MB, which makes it ideal for the smaller USB Flash drives. Secondly, it's read in blocks (64k blocks by default), and the kernel will only cache a few blocks at a time; as a result, SquashFS doesn't take up much memory at all when it's running.</p>
<p>Setting up the image is a simple matter of calling the compressor:</p>
<samp>
 <h3>Making the SquashFS image</h3>
 <pre># cd /root/fscopy
# mksquashfs * ../filesystem.squash</pre>
</samp>
<h2>Stage 2a: Patching the kernel</h2>
<p>Now, if you're lucky, you'll already have kernel support for SquashFS, and for UnionFS which we'll be using later. Those of you running Ubuntu Feisty, for example, will already have the modules, and don't need to do anything further. You can find out if you're one of the lucky people quite easily:</p>
<samp>
 <h3>Checking for pre-existing modules</h3>
 <pre># modprobe squashfs
# modprobe unionfs
# mount -o loop /root/filesystem.squash /mnt</pre>
</samp>
<p>If these commands all run fine, and you can see your squashed filesystem in <code>/mnt</code>, then you don't need to do any more work on the kernel. If, however, you're a masochist like myself, you'll have to compile your own kernel containing SquashFS and UnionFS. Unfortunately, these eminently useful filesystems aren't in the default kernel package, so you'll have to patch the kernel tree:</p>
<samp>
 <h3>Downloading and applying patches</h3>
 <pre># cd /usr/src
# wget http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.22.9.tar.bz2
# tar xjf linux-2.6.22.9.tar.bz2
# wget http://switch.dl.sourceforge.net/sourceforge/squashfs/squashfs3.2-r2.tar.gz
# tar xzf squashfs3.2-r2.tar.gz
# cd linux-2.6.22.9
# patch -p1 &lt; ../squashfs3.2-r2/kernel-patches/linux-2.6.20/squashfs3.2-patch
# wget -O- http://download.filesystems.org/unionfs/unionfs-2.1/unionfs-2.1.6_for_2.6.22.9.diff.gz | gunzip | patch -p1</pre>
</samp>
<p>Of course, these packages are current as of October '07, and will change with time. At the moment, the above lines will complete successfully.</p>
<p>Once the patches have been applied successfully, you can build your kernel as normal, including all the drivers and modules as normal, but also including the two patches:</p>
<samp>
 <h3>Selecting the patches</h3>
 <pre>File systems -&gt;
  Layered filesystems -&gt;
    &lt;M&gt; Union file system
  Miscellaneous filesystems -&gt;
    &lt;M&gt; SquashFS 3.2 - Squashed file system support</pre>
</samp>
<h2>Stage 2b: Booting the kernel</h2>
<p>Whether you've built your own kernel or using the one shipped with your distribution, the next step in the process is to get it booting. Since the USB Flash disk has a filesystem, it should be a simple matter of copying the kernel file over and applying some magic; that magic comes in the form of SysLinux, a small package which boots a kernel from a variety of situations. In order to use SysLinux, it first has to be installed; on Gentoo Linux, the installation would run as follows:</p>
<samp>
 <h3>Installing SysLinux</h3>
 <pre># emerge syslinux</pre>
</samp>
<p>SysLinux provides a boot system from which the Linux kernel can be started; it does this by adding a bootsector and system file to the FAT partition on which it's installed. Performing this installation couldn't be simpler:</p>
<samp>
 <h3>Placing SysLinux on the Flash drive</h3>
 <pre># syslinux /dev/sda1</pre>
</samp>
<p>When SysLinux starts booting, it will look to a configuration file called <code>syslinux.cfg</code>, in order to find out what to do. You can make the configuration file complex, with multiple kernels and various options between which you can select at boot-time; in this case, we need the simplest possible configuration:</p>
<samp>
 <h3><code>syslinux.cfg</code>: Booting the kernel</h3>
 <pre>default kernel.img</pre>
</samp>
<p>This configuration will force SysLinux to look for a Linux kernel file, called <code>kernel.img</code>, and load it. Now all that's required is to copy the kernel over: depending on which route you took above, the kernel will either be inside the kernel source tree, or sitting in <code>/boot</code>. I compiled my kernel, so I ran the following:</p>
<samp>
 <h3>Copying the kernel image</h3>
 <pre># mount /dev/sda1 /mnt/flash
# cp /usr/src/linux-2.6.22.9/arch/i386/boot/bzImage /mnt/flash/kernel.img</pre>
</samp>
<p>Now you'll be able to boot Linux from the Flash drive. Unfortunately, you won't get very far before you hit a kernel panic; no root device was specified, so the boot falls over. To allow the rest of the operating system to boot, a temporary root filesystem is required: that's what I'll build next.</p>
<h2>Stage 3a: Building an initial root</h2>
<p>Now, I could just use the SquashFS image as the root disk, and let it be. There are problems with that, though: namely that the SquashFS image is read-only, and we'll need a system that can accommodate changes to stuff like the log files. Fortunately, there is a way to allow this, which is to overlay a temporary file system on the SquashFS image, and write changes to that.</p>
<p>In order to set this up, we need an intermediate step between the kernel and the filesystem image, which can perform the overlay and then "pivot" over to the actual root image. The kernel has a feature which allows it to do this: the <code>initrd</code>, or initial root disk, which can be loaded into RAM. The initrd can contain anything you like, as long as it's relatively small: as the whole disk image is loaded into RAM, it has to leave room for the root filesystem proper.</p>
<p>Building the initial root disk is a less complicated affair than putting together the SquashFS image, and it starts by allocating some space for the image. I've used 8MB, since it's ample room for everything we'll need:</p>
<samp>
 <h3>Initialising the initrd</h3>
 <pre># dd if=/dev/zero of=/root/initrd bs=1M count=8
# mke2fs /root/initrd
# mount -o loop /root/initrd /mnt/initrd</pre>
</samp>
<p>Once the initrd has been filled in with a filesystem, and mounted somewhere, we can add stuff to it. The first things that are required are a basic directory structure, and a few device nodes:</p>
<samp>
 <h3>Filling out the initrd</h3>
 <pre># cd /mnt/initrd
# mkdir -p bin dev etc lib/modules mnt proc sbin tmp usr/bin usr/sbin var/lib
# for a in {0,1,2,3,4,5,6,7}; do mkdir mnt/$a; done
# for a in {tty*,console,null}; do cp `find /dev -maxdepth 1 -name "$a" -type c` dev; done
# for a in {hd*,sd*,fd*}; do cp `find /dev -maxdepth 1 -name "$a" -type b` dev; done</pre>
</samp>
<h2>Stage 3b: Filling in the initrd</h2>
<p>Once the initrd has a basic structure, it needs some executable utilities in order to do anything: commands like <code>sh</code>, <code>mount</code> and <code>cp</code> all have to be provided. Fortunately, there's a nifty package called BusyBox which compiles all the utilities one could possibly need into one binary file. The configuration process for BusyBox is something I won't be covering in great detail, but it's very similar to the Linux kernel configuration: a system of menus is provided, from which selections can be made. Be aware that you'll have to compile BusyBox as a statically-linked binary, otherwise the initrd will require not just the executable, but the libraries on which it depends.</p>
<samp>
 <h3>Compiling BusyBox</h3>
 <pre># wget http://busybox.net/downloads/busybox-1.7.2.tar.bz2
# tar xjf busybox-1.7.2.tar.bz2
# cd busybox-1.7.2
# make menuconfig
# make</pre>
</samp>
<p>I've provided a copy of the initrd below, for those who are less willing to run through the above process. It contains the basic directory structure, along with the device nodes and a statically compiled copy of BusyBox:</p>
<p><a href="http://oopsilon.com/software/linux-initrd.gz">http://oopsilon.com/software/linux-initrd.gz</a> [1.1MB]</p>
<p>What's missing from the initrd is a copy of the modules associated with the kernel. You can retrieve these from <code>/lib/modules</code> and simply copy them over to the initrd; in the example below, I'm copying the modules from the 2.6.22.9 kernel I compiled earlier:</p>
<samp>
 <h3>Copying kernel modules to the initrd</h3>
 <pre># cp -a /lib/modules/linux-2.6.22.9 /mnt/initrd/lib/modules</pre>
</samp>
<h2>Stage 3c: Mounting the real root</h2>
<p>The final step in the initrd is to give it a purpose: at present, it's a collection of binaries and device nodes with nothing to do. We have an initial root disk and a kernel, but no way to link the two: the kernel should load and boot the initrd. This is done by giving parameters to the kernel when it boots, and that's done from the SysLinux configuration:</p>
<samp>
 <h3><code>syslinux.cfg</code>: Including the initrd</h3>
 <pre>default kernel.img initrd=initrd.gz root=/dev/ram0 ramdisk_size=8192 rw init=/linuxrc</pre>
</samp>
<p>As can be seen in this configuration, the kernel is told to run a file called <code>linuxrc</code> on the initrd, as the initialisation script. I've provided a simple <code>linuxrc</code> on the initrd image linked above; all it does is load a shell:</p>
<samp>
 <h3><code>linuxrc</code>: Sample init file</h3>
 <pre>#!/bin/msh
mount -t proc proc /proc
clear
exec /bin/msh</pre>
</samp>
<p>You may have guessed that this file can contain just about anything, as long as it uses commands supplied by BusyBox. We can mount the SquashFS root filesystem, overlay a temporary RAM disk on top and start up the new root, with the following script:</p>
<samp>
 <h3><code>linuxrc</code>: Pivoting to the real root</h3>
 <pre>#!/bin/msh
echo Initial root disk loaded. Proceeding.

# Mount the proc filesystem, and the Flash disk
mount -t proc proc /proc
mount /dev/sda1 /mnt/0

# Find the SquashFS image on the Flash disk, and mount it
mount /mnt/0/newroot.sfs /mnt/1

# Mount a temporary filesystem, to use as the overlay
mount -t tmpfs -o size=100M tmpfs /mnt/2

# Perform the overlay with UnionFS, with tmpfs as read/write
# and the SquashFS as read-only
mount -t unionfs -o dirs=/mnt/2=rw:/mnt/1=ro /mnt/1 /mnt/3

# Pivot to the new root
cd /mnt/3
mkdir initrd
pivot_root . initrd

# Enter the new root, and run init
exec chroot . /sbin/init &lt;/dev/console &gt;/dev/console 2&gt;&amp;1</pre>
</samp>
<p>You may have to change the device reference for the Flash disk, depending on the kernel you use: if you boot the initrd with the simple shell-exec script I provided above, and check the output of <code>dmesg</code>, you should be able to see where the kernel has loaded from.</p>
<h2>Stage 4: Finalising and testing</h2>
<p>With the new <code>linuxrc</code>, the initrd is complete, and can now be unmounted and compressed:</p>
<samp>
 <h3>Compressing the initrd</h3>
 <pre># umount /mnt/initrd
# gzip -9 /root/initrd
# cp /root/initrd.gz /mnt/flash
# umount /mnt/flash</pre>
</samp>
<p>And that should be that. Throw the Flash disk into a spare computer, and watch it boot: it should look just like your hard disk's boot process. If it doesn't, the cause may be one of a few things:</p>
<dl>
 <dt>Kernel panic: No <code>root</code> or no <code>init</code></dt>
 <dd>Remember that in order to use initial root disks, the support must be compiled in (not just built as a module) into the kernel; furthermore, the options must be specified on the SysLinux configuration line.</dd>
 <dt>The initrd shows a message, but nothing else happens</dt>
 <dd>Ensure that the correct device name is being used by <code>linuxrc</code> for the Flash disk; if the script can't find the Flash disk, things will fall over.</dd>
 <dt><code>init</code> fails to read <code>/dev/initctl</code></dt>
 <dd>The SYSV <code>init</code> script, as used by most Linux distributions, uses a FIFO called <code>/dev/initctl</code> to communicate and change runlevels; if this node doesn't exist on the SquashFS root, <code>init</code> will fail.</dd>
</dl>
<p>If you have any more obscure errors, feel free to get in touch with either myself or your local Linux support channel; also, please let me know if you manage to get this setup working. The procedure above was quite smooth for me, but in the eternal clause of the technical tutorial, <em>your mileage may vary</em>.</p>
<p><em>Copyright Imran Nazar &lt;<a href="mailto:tf@oopsilon.com">tf@oopsilon.com</a>&gt;, 2007</em></p>
 ]]></content>
</entry>
<entry>
 <title type="html">ARMv4/5 Opcode Map</title>
 <link href="https://imrannazar.com/articles/arm-opcode-map" rel="alternate" type="text/html" title="ARMv4/5 Opcode Map" />
 <id>https://imrannazar.com/articles/arm-opcode-map</id>
 <summary>There are many places in which you can look if you want an explanation of the instructions available on the ARM series of processor cores. However, there is no overview of the instruction set in the form of a table or map; not even the official ARM instruction reference provides this anywhere in its 811 pages. I produced an opcode map in 2006, in an attempt to rectify this problem: it provides a mapping of all the instructions and addressing modes for cores up to ARM version 4, with version 5 extensions highlighted in blue and the DSP extensions in green.</summary>
 <category term="Articles" />
 <published>Thu, 04 Oct 2007 20:13:03 +0000</published>
 <content type="text/html"><![CDATA[
     <style>
#opcodemaps table { font-size: 0.7em; margin: 0 auto 3em; padding: 0; border-collapse:collapse; }
#opcodemaps caption { font-size:1.25em; font-style:italic; }
#opcodemaps td { vertical-align: middle; margin: 0px; padding: 3px; border: 1px solid #444; width:2em; text-align: center; }
#opcodemaps th { margin: 1px; padding: 3px; border: 1px solid black; background:#ccc; }
#opcodemaps td span { text-decoration: none; border-bottom: 1px dotted #aaa; }
#opcodemaps td.bit { vertical-align: middle; text-align: right; background: #ccc; border: 1px solid black; }
#opcodemaps td.arm9 { background: #aaf; }
#opcodemaps td.edsp { background: #afa; }
#opcodemaps td.und { background: #faa; }
  </style>
  <p><strong>Update, Nov 2023</strong>: <a href="https://hachyderm.io/@cliffle">Cliff Biffle</a> has put together a <a href="https://docs.google.com/spreadsheets/d/1wzb5pbs7TSC63n5LNe4eYMe-3MTcLU-UzBjMo3VUHys/edit#gid=429539096">Thumb-2 opcode map for M-profile ARM cores (Google Sheet)</a>, which may be more relevant to modern interests than the ARMv4/5 opcode map; my map remains below for posterity.</p>
  <hr>
  <p>The following is a full opcode map of instructions for the ARM7 and ARM9 series of CPU cores. Instructions added for ARM9 are highlighted in blue, and instructions specific to the M-extension are shown in green. The Thumb instruction set is also included, in Table 2.</p>
  <div id="opcodemaps">
  <table>
   <caption>Table 1. ARM Opcode Map.</caption>
   <thead>
    <tr>
     <th rowspan='2'>Bits<br>27-20</th>
     <th colspan='16'>Bits 7-4</th>
    </tr>
    <tr>
     <th>0</th><th>1</th><th>2</th><th>3</th>
     <th>4</th><th>5</th><th>6</th><th>7</th>
     <th>8</th><th>9</th><th>A</th><th>B</th>
     <th>C</th><th>D</th><th>E</th><th>F</th>
    </tr>
   </thead>
   <tbody>
<tr>
 <td class='bit'>00</td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical And'>AND</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical And'>AND</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical And'>AND</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical And'>AND</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Multiply registers'>MUL</span></td>
 <td><span title='Logical And'>AND</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical And'>AND</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical And'>AND</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, post-decrement'>ptrm</span></td>
</tr>
<tr>
 <td class='bit'>01</td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Multiply registers, setting flags'>MULS</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical And, setting flags'>ANDS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
</tr>
<tr>
 <td class='bit'>02</td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Multiply and accumulate registers'>MLA</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, post-decrement'>ptrm</span></td>
</tr>
<tr>
 <td class='bit'>03</td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Multiply and accumulate registers, setting flags'>MLAS</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, post-decrement'>ptrm</span></td>
 <td><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, post-decrement'>ptrm</span></td>
</tr>
<tr>
 <td class='bit'>04</td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>05</td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract, setting flags'>SUBS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>06</td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Subtract register from value'>RSB</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>07</td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
 <td><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>08</td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Unsigned long multiply (32x32 to 64)'>UMULL</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register'>ADD</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, post-increment'>ptrp</span></td>
</tr>
<tr>
 <td class='bit'>09</td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Unsigned long multiply, setting flags'>UMULLS</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register, setting flags'>ADDS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, post-increment'>ptrp</span></td>
</tr>
<tr>
 <td class='bit'>0A</td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Unsigned long multiply and accumulate'>UMLAL</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register with carry'>ADC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, post-increment'>ptrp</span></td>
</tr>
<tr>
 <td class='bit'>0B</td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Unsigned long multiply and accumulate, setting flags'>UMLALS</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, post-increment'>ptrp</span></td>
 <td><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, post-increment'>ptrp</span></td>
</tr>
<tr>
 <td class='bit'>0C</td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Signed long multiply (32x32 to 64)'>SMULL</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract from register with borrow'>SBC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>0D</td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Signed long multiply, setting flags'>SMULLS</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>0E</td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Signed long multiply and accumulate'>SMLAL</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract register from value with borrow'>RSC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>0F</td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Signed long multiply and accumulate, setting flags'>SMLALS</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, post-increment'>ptip</span></td>
 <td><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>10</td>
 <td><span title='Move status word to register'>MRS</span> <span title='Register, CPSR'>rc</span></td>
 <td class='und' colspan='4'></td>
 <td class='edsp'><span title='Saturated add'>QADD</span></td>
 <td class='und' colspan='2'></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with bottom-half of second, and accumulate'>SMLABB</span></td>
 <td><span title='Swap registers with memory word'>SWP</span></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with bottom-half of second, and accumulate'>SMLATB</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Negative register offset'>ofrm</span></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with top-half of second, and accumulate'>SMLABT</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Negative register offset'>ofrm</span></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with top-half of second, and accumulate'>SMLATT</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Negative register offset'>ofrm</span></td>
</tr>
<tr>
 <td class='bit'>11</td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Negative register offset'>ofrm</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Negative register offset'>ofrm</span></td>
 <td><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Negative register offset'>ofrm</span></td>
</tr>
<tr>
 <td class='bit'>12</td>
 <td><span title='Move value to status word'>MSR</span> <span title='Register, CPSR'>rc</span></td>
 <td><span title='Branch and switch execution modes'>BX</span></td>
 <td class='und'></td>
 <td class='arm9'><span title='Branch, link and switch execution modes '>BLX</span> <span title='Register offset'>reg</span></td>
 <td class='und'></td>
 <td class='edsp'><span title='Saturated subtract'>QSUB</span></td>
 <td class='und'></td>
 <td class='arm9'><span title='Software breakpoint'>BKPT</span></td>
 <td class='edsp'><span title='Signed multiply first operand with bottom-half of second operand, keeping top 32 bits, and accumulate'>SMLAWB</span></td>
 <td class='und'></td>
 <td class='edsp'><span title='Signed multiply first operand with bottom-half of second operand, keeping top 32 bits'>SMULWB</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, pre-decrement'>prrm</span></td>
 <td class='edsp'><span title='Signed multiply first operand with top-half of second operand, keeping top 32 bits, and accumulate'>SMLAWT</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, pre-decrement'>prrm</span></td>
 <td class='edsp'><span title='Signed multiply first operand with top-half of second operand, keeping top 32 bits'>SMULWT</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, pre-decrement'>prrm</span></td>
</tr>
<tr>
 <td class='bit'>13</td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, pre-decrement'>prrm</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, pre-decrement'>prrm</span></td>
 <td><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, pre-decrement'>prrm</span></td>
</tr>
<tr>
 <td class='bit'>14</td>
 <td><span title='Move status word to register'>MRS</span> <span title='Register, SPSR'>rs</span></td>
 <td class='und' colspan='4'></td>
 <td class='edsp'><span title='Saturated add with doubling of second operand'>QDADD</span></td>
 <td class='und' colspan='2'></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with bottom-half of second, and 64-bit accumulate'>SMLALBB</span></td>
 <td><span title='Swap registers with memory byte'>SWPB</span></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with bottom-half of second, and 64-bit accumulate'>SMLALTB</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Negative immediate offset'>ofim</span></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with top-half of second, and 64-bit accumulate'>SMLALBT</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Negative immediate offset'>ofim</span></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with top-half of second, and 64-bit accumulate'>SMLALTT</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>15</td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Negative immediate offset'>ofim</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Negative immediate offset'>ofim</span></td>
 <td><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>16</td>
 <td><span title='Move value to status word'>MSR</span> <span title='Register, SPSR'>rs</span></td>
 <td class='arm9'><span title='Count leading zeros in register'>CLZ</span></td>
 <td class='und' colspan='3'></td>
 <td class='edsp'><span title='Saturated subtract with doubling of second operand'>QDSUB</span></td>
 <td class='und' colspan='2'></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with bottom-half of second'>SMULBB</span></td>
 <td class='und'></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with bottom-half of second'>SMULTB</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
 <td class='edsp'><span title='Signed multiply bottom-half of first operand with top-half of second'>SMULBT</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
 <td class='edsp'><span title='Signed multiply top-half of first operand with top-half of second'>SMULTT</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>17</td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
 <td><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>18</td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Logical Or'>ORR</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Positive register offset'>ofrp</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Positive register offset'>ofrp</span></td>
 <td><span title='Logical Or'>ORR</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Positive register offset'>ofrp</span></td>
</tr>
<tr>
 <td class='bit'>19</td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Positive register offset'>ofrp</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Positive register offset'>ofrp</span></td>
 <td><span title='Logical Or, setting flags'>ORRS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Positive register offset'>ofrp</span></td>
</tr>
<tr>
 <td class='bit'>1A</td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Register offset, pre-increment'>prrp</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Register offset, pre-increment'>prrp</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Register offset, pre-increment'>prrp</span></td>
</tr>
<tr>
 <td class='bit'>1B</td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Register offset, pre-increment'>prrp</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Register offset, pre-increment'>prrp</span></td>
 <td><span title='Move value to a register, setting flags'>MOVS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Register offset, pre-increment'>prrp</span></td>
</tr>
<tr>
 <td class='bit'>1C</td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Positive immediate offset'>ofip</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Positive immediate offset'>ofip</span></td>
 <td><span title='Clear bits in register (NAND)'>BIC</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>1D</td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Positive immediate offset'>ofip</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Positive immediate offset'>ofip</span></td>
 <td><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>1E</td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Store halfword'>STRH</span> <span title='Immediate offset, pre-increment'>prip</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td class='edsp'><span title='Load doubleword'>LDRD</span> <span title='Immediate offset, pre-increment'>prip</span></td>
 <td><span title='Move negation of value to a register'>MVN</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td class='edsp'><span title='Store doubleword'>STRD</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>1F</td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-left by register'>llr</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-right by register'>lrr</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Arithmetic shift-right by register'>arr</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Rotate right by register'>rrr</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-left by immediate'>lli</span></td>
 <td class='und'></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Logical shift-right by immediate'>lri</span></td>
 <td><span title='Load halfword'>LDRH</span> <span title='Immediate offset, pre-increment'>prip</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Arithmetic shift-right by immediate'>ari</span></td>
 <td><span title='Load signed byte'>LDRSB</span> <span title='Immediate offset, pre-increment'>prip</span></td>
 <td><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Rotate right by immediate, or rotate right with extend (RRX)'>rri</span></td>
 <td><span title='Load signed halfword'>LDRSH</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>20</td>
 <td colspan='16'><span title='Logical And'>AND</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>21</td>
 <td colspan='16'><span title='Logical And, setting flags'>ANDS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>22</td>
 <td colspan='16'><span title='Logical Exclusive-or'>EOR</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>23</td>
 <td colspan='16'><span title='Logical Exclusive-or, setting flags'>EORS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>24</td>
 <td colspan='16'><span title='Subtract from register'>SUB</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>25</td>
 <td colspan='16'><span title='Subtract, setting flags'>SUBS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>26</td>
 <td colspan='16'><span title='Subtract register from value'>RSB</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>27</td>
 <td colspan='16'><span title='Reverse Subtract, setting flags'>RSBS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>28</td>
 <td colspan='16'><span title='Add to register'>ADD</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>29</td>
 <td colspan='16'><span title='Add to register, setting flags'>ADDS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2A</td>
 <td colspan='16'><span title='Add to register with carry'>ADC</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2B</td>
 <td colspan='16'><span title='Add to register with carry, setting flags'>ADCS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2C</td>
 <td colspan='16'><span title='Subtract from register with borrow'>SBC</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2D</td>
 <td colspan='16'><span title='Subtract from register with borrow, setting flags'>SBCS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2E</td>
 <td colspan='16'><span title='Subtract register from value with borrow'>RSC</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>2F</td>
 <td colspan='16'><span title='Subtract register from value with borrow, setting flags'>RSCS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>30</td>
 <td class='und' colspan='16'></td>
</tr>
<tr>
 <td class='bit'>31</td>
 <td colspan='16'><span title='Test bits in register (Logical And), setting flags'>TSTS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>32</td>
 <td colspan='16'><span title='Move value to status word'>MSR</span> <span title='Immediate, CPSR'>ic</span></td>
</tr>
<tr>
 <td class='bit'>33</td>
 <td colspan='16'><span title='Test equivalence of bits in register (Logical Exclusive-or), setting flags'>TEQS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>34</td>
 <td class='und' colspan='16'></td>
</tr>
<tr>
 <td class='bit'>35</td>
 <td colspan='16'><span title='Compare register to value (Subtract), setting flags'>CMPS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>36</td>
 <td colspan='16'><span title='Move value to status word'>MSR</span> <span title='Immediate, SPSR'>is</span></td>
</tr>
<tr>
 <td class='bit'>37</td>
 <td colspan='16'><span title='Compare register to negation of value (Add), setting flags'>CMNS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>38</td>
 <td colspan='16'><span title='Logical Or'>ORR</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>39</td>
 <td colspan='16'><span title='Logical Or, setting flags'>ORRS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3A</td>
 <td colspan='16'><span title='Move value to a register'>MOV</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3B</td>
 <td colspan='16'><span title='Move value to a register, setting flags'>MOVS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3C</td>
 <td colspan='16'><span title='Clear bits in register (NAND)'>BIC</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3D</td>
 <td colspan='16'><span title='Clear bits in register (NAND), setting flags'>BICS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3E</td>
 <td colspan='16'><span title='Move negation of value to a register'>MVN</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>3F</td>
 <td colspan='16'><span title='Move negation of value to a register, setting flags'>MVNS</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>40</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>41</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>42</td>
 <td colspan='16'><span title='Store word from user-mode register'>STRT</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>43</td>
 <td colspan='16'><span title='Load word into user-mode register'>LDRT</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>44</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>45</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>46</td>
 <td colspan='16'><span title='Store byte from user-mode register'>STRBT</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>47</td>
 <td colspan='16'><span title='Load byte into user-mode register'>LDRBT</span> <span title='Immediate offset, post-decrement'>ptim</span></td>
</tr>
<tr>
 <td class='bit'>48</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>49</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4A</td>
 <td colspan='16'><span title='Store word from user-mode register'>STRT</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4B</td>
 <td colspan='16'><span title='Load word into user-mode register'>LDRT</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4C</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4D</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4E</td>
 <td colspan='16'><span title='Store byte from user-mode register'>STRBT</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>4F</td>
 <td colspan='16'><span title='Load byte into user-mode register'>LDRBT</span> <span title='Immediate offset, post-increment'>ptip</span></td>
</tr>
<tr>
 <td class='bit'>50</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>51</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>52</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>53</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>54</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>55</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Negative immediate offset'>ofim</span></td>
</tr>
<tr>
 <td class='bit'>56</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>57</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Immediate offset, pre-decrement'>prim</span></td>
</tr>
<tr>
 <td class='bit'>58</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>59</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>5A</td>
 <td colspan='16'><span title='Store word'>STR</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>5B</td>
 <td colspan='16'><span title='Load word'>LDR</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>5C</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>5D</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Positive immediate offset'>ofip</span></td>
</tr>
<tr>
 <td class='bit'>5E</td>
 <td colspan='16'><span title='Store byte'>STRB</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>5F</td>
 <td colspan='16'><span title='Load byte'>LDRB</span> <span title='Immediate offset, pre-increment'>prip</span></td>
</tr>
<tr>
 <td class='bit'>60</td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>61</td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>62</td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>63</td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>64</td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>65</td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>66</td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>67</td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Left-shifted register offset, post-decrement'>ptrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-shifted register offset, post-decrement'>ptrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Arithmetic-right-shifted register offset, post-decrement'>ptrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-rotated register offset, post-decrement'>ptrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>68</td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>69</td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6A</td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word from user-mode register'>STRT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6B</td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word into user-mode register'>LDRT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6C</td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6D</td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6E</td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte from user-mode register'>STRBT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>6F</td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Left-shifted register offset, post-increment'>ptrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-shifted register offset, post-increment'>ptrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Arithmetic-right-shifted register offset, post-increment'>ptrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte into user-mode register'>LDRBT</span> <span title='Right-rotated register offset, post-increment'>ptrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>70</td>
 <td><span title='Store word'>STR</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>71</td>
 <td><span title='Load word'>LDR</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>72</td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>73</td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>74</td>
 <td><span title='Store byte'>STRB</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>75</td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative left-shifted register offset'>ofrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative right-shifted register offset'>ofrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative arithmetic-right-shifted register offset'>ofrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Negative right-rotated register offset'>ofrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>76</td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>77</td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, pre-decrement'>prrmll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, pre-decrement'>prrmlr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, pre-decrement'>prrmar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, pre-decrement'>prrmrr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>78</td>
 <td><span title='Store word'>STR</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>79</td>
 <td><span title='Load word'>LDR</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7A</td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Store word'>STR</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7B</td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Load word'>LDR</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7C</td>
 <td><span title='Store byte'>STRB</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7D</td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive left-shifted register offset'>ofrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive right-shifted register offset'>ofrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive arithmetic-right-shifted register offset'>ofrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Positive right-rotated register offset'>ofrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7E</td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Store byte'>STRB</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>7F</td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Left-shifted register offset, pre-increment'>prrpll</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-shifted register offset, pre-increment'>prrplr</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Arithmetic-right-shifted register offset, pre-increment'>prrpar</span></td>
 <td class='und'></td>
 <td><span title='Load byte'>LDRB</span> <span title='Right-rotated register offset, pre-increment'>prrprr</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>80</td>
 <td colspan='16'><span title='Store multiple words, decrement after'>STMDA</span></td>
</tr>
<tr>
 <td class='bit'>81</td>
 <td colspan='16'><span title='Load multiple words, decrement after'>LDMDA</span></td>
</tr>
<tr>
 <td class='bit'>82</td>
 <td colspan='16'><span title='Store multiple words, decrement after'>STMDA</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>83</td>
 <td colspan='16'><span title='Load multiple words, decrement after'>LDMDA</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>84</td>
 <td colspan='16'><span title='Store multiple words, decrement after'>STMDA</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>85</td>
 <td colspan='16'><span title='Load multiple words, decrement after'>LDMDA</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>86</td>
 <td colspan='16'><span title='Store multiple words, decrement after'>STMDA</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>87</td>
 <td colspan='16'><span title='Load multiple words, decrement after'>LDMDA</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>88</td>
 <td colspan='16'><span title='Store multiple words, increment after'>STMIA</span></td>
</tr>
<tr>
 <td class='bit'>89</td>
 <td colspan='16'><span title='Load multiple words, increment after'>LDMIA</span></td>
</tr>
<tr>
 <td class='bit'>8A</td>
 <td colspan='16'><span title='Store multiple words, increment after'>STMIA</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>8B</td>
 <td colspan='16'><span title='Load multiple words, increment after'>LDMIA</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>8C</td>
 <td colspan='16'><span title='Store multiple words, increment after'>STMIA</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>8D</td>
 <td colspan='16'><span title='Load multiple words, increment after'>LDMIA</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>8E</td>
 <td colspan='16'><span title='Store multiple words, increment after'>STMIA</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>8F</td>
 <td colspan='16'><span title='Load multiple words, increment after'>LDMIA</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>90</td>
 <td colspan='16'><span title='Store multiple words, decrement before'>STMDB</span></td>
</tr>
<tr>
 <td class='bit'>91</td>
 <td colspan='16'><span title='Load multiple words, decrement before'>LDMDB</span></td>
</tr>
<tr>
 <td class='bit'>92</td>
 <td colspan='16'><span title='Store multiple words, decrement before'>STMDB</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>93</td>
 <td colspan='16'><span title='Load multiple words, decrement before'>LDMDB</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>94</td>
 <td colspan='16'><span title='Store multiple words, decrement before'>STMDB</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>95</td>
 <td colspan='16'><span title='Load multiple words, decrement before'>LDMDB</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>96</td>
 <td colspan='16'><span title='Store multiple words, decrement before'>STMDB</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>97</td>
 <td colspan='16'><span title='Load multiple words, decrement before'>LDMDB</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>98</td>
 <td colspan='16'><span title='Store multiple words, increment before'>STMIB</span></td>
</tr>
<tr>
 <td class='bit'>99</td>
 <td colspan='16'><span title='Load multiple words, increment before'>LDMIB</span></td>
</tr>
<tr>
 <td class='bit'>9A</td>
 <td colspan='16'><span title='Store multiple words, increment before'>STMIB</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>9B</td>
 <td colspan='16'><span title='Load multiple words, increment before'>LDMIB</span> <span title='Write back'>w</span></td>
</tr>
<tr>
 <td class='bit'>9C</td>
 <td colspan='16'><span title='Store multiple words, increment before'>STMIB</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>9D</td>
 <td colspan='16'><span title='Load multiple words, increment before'>LDMIB</span> <span title='Use user-mode registers'>u</span></td>
</tr>
<tr>
 <td class='bit'>9E</td>
 <td colspan='16'><span title='Store multiple words, increment before'>STMIB</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>9F</td>
 <td colspan='16'><span title='Load multiple words, increment before'>LDMIB</span> <span title='Use user-mode registers, with write back'>uw</span></td>
</tr>
<tr>
 <td class='bit'>A0</td>
 <td rowspan='16' colspan='16'><span title='Branch'>B</span></td>
</tr>
<tr>
 <td class='bit'>A1</td>
</tr>
<tr>
 <td class='bit'>A2</td>
</tr>
<tr>
 <td class='bit'>A3</td>
</tr>
<tr>
 <td class='bit'>A4</td>
</tr>
<tr>
 <td class='bit'>A5</td>
</tr>
<tr>
 <td class='bit'>A6</td>
</tr>
<tr>
 <td class='bit'>A7</td>
</tr>
<tr>
 <td class='bit'>A8</td>
</tr>
<tr>
 <td class='bit'>A9</td>
</tr>
<tr>
 <td class='bit'>AA</td>
</tr>
<tr>
 <td class='bit'>AB</td>
</tr>
<tr>
 <td class='bit'>AC</td>
</tr>
<tr>
 <td class='bit'>AD</td>
</tr>
<tr>
 <td class='bit'>AE</td>
</tr>
<tr>
 <td class='bit'>AF</td>
</tr>
<tr>
 <td class='bit'>B0</td>
 <td rowspan='16' colspan='16'><span title='Branch and link'>BL</span></td>
</tr>
<tr>
 <td class='bit'>B1</td>
</tr>
<tr>
 <td class='bit'>B2</td>
</tr>
<tr>
 <td class='bit'>B3</td>
</tr>
<tr>
 <td class='bit'>B4</td>
</tr>
<tr>
 <td class='bit'>B5</td>
</tr>
<tr>
 <td class='bit'>B6</td>
</tr>
<tr>
 <td class='bit'>B7</td>
</tr>
<tr>
 <td class='bit'>B8</td>
</tr>
<tr>
 <td class='bit'>B9</td>
</tr>
<tr>
 <td class='bit'>BA</td>
</tr>
<tr>
 <td class='bit'>BB</td>
</tr>
<tr>
 <td class='bit'>BC</td>
</tr>
<tr>
 <td class='bit'>BD</td>
</tr>
<tr>
 <td class='bit'>BE</td>
</tr>
<tr>
 <td class='bit'>BF</td>
</tr>
<tr>
 <td class='bit'>C0</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Negative offset'>ofm</span></td>
</tr>
<tr>
 <td class='bit'>C1</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Negative offset'>ofm</span></td>
</tr>
<tr>
 <td class='bit'>C2</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Pre-decrement'>prm</span></td>
</tr>
<tr>
 <td class='bit'>C3</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Pre-decrement'>prm</span></td>
</tr>
<tr>
 <td class='bit'>C4</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Negative offset'>ofm</span></td>
</tr>
<tr>
 <td class='bit'>C5</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Negative offset'>ofm</span></td>
</tr>
<tr>
 <td class='bit'>C6</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Pre-decrement'>prm</span></td>
</tr>
<tr>
 <td class='bit'>C7</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Pre-decrement'>prm</span></td>
</tr>
<tr>
 <td class='bit'>C8</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Positive offset'>ofp</span></td>
</tr>
<tr>
 <td class='bit'>C9</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Positive offset'>ofp</span></td>
</tr>
<tr>
 <td class='bit'>CA</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Pre-increment'>prp</span></td>
</tr>
<tr>
 <td class='bit'>CB</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Pre-increment'>prp</span></td>
</tr>
<tr>
 <td class='bit'>CC</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Positive offset'>ofp</span></td>
</tr>
<tr>
 <td class='bit'>CD</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Positive offset'>ofp</span></td>
</tr>
<tr>
 <td class='bit'>CE</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Pre-increment'>prp</span></td>
</tr>
<tr>
 <td class='bit'>CF</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Pre-increment'>prp</span></td>
</tr>
<tr>
 <td class='bit'>D0</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Unindexed, bits 7-0 available for copro use'>unm</span></td>
</tr>
<tr>
 <td class='bit'>D1</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Unindexed, bits 7-0 available for copro use'>unm</span></td>
</tr>
<tr>
 <td class='bit'>D2</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Post-decrement'>ptm</span></td>
</tr>
<tr>
 <td class='bit'>D3</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Post-decrement'>ptm</span></td>
</tr>
<tr>
 <td class='bit'>D4</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Unindexed, bits 7-0 available for copro use'>unm</span></td>
</tr>
<tr>
 <td class='bit'>D5</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Unindexed, bits 7-0 available for copro use'>unm</span></td>
</tr>
<tr>
 <td class='bit'>D6</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Post-decrement'>ptm</span></td>
</tr>
<tr>
 <td class='bit'>D7</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Post-decrement'>ptm</span></td>
</tr>
<tr>
 <td class='bit'>D8</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Unindexed, bits 7-0 available for copro use'>unp</span></td>
</tr>
<tr>
 <td class='bit'>D9</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Unindexed, bits 7-0 available for copro use'>unp</span></td>
</tr>
<tr>
 <td class='bit'>DA</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Post-increment'>ptp</span></td>
</tr>
<tr>
 <td class='bit'>DB</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Post-increment'>ptp</span></td>
</tr>
<tr>
 <td class='bit'>DC</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Unindexed, bits 7-0 available for copro use'>unp</span></td>
</tr>
<tr>
 <td class='bit'>DD</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Unindexed, bits 7-0 available for copro use'>unp</span></td>
</tr>
<tr>
 <td class='bit'>DE</td>
 <td colspan='16'><span title='Store coprocessor data to memory'>STC</span> <span title='Post-increment'>ptp</span></td>
</tr>
<tr>
 <td class='bit'>DF</td>
 <td colspan='16'><span title='Load coprocessor data from memory'>LDC</span> <span title='Post-increment'>ptp</span></td>
</tr>
<tr>
 <td class='bit'>E0</td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
 <td rowspan='16'><span title='Perform coprocessor data operation'>CDP</span></td>
 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>E1</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
 
 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>E2</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>E3</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>E4</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>E5</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>E6</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>E7</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>E8</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>E9</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>EA</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>EB</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>EC</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>ED</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>EE</td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>

 <td><span title='Write coprocessor register from ARM register'>MCR</span></td>
</tr>
<tr>
 <td class='bit'>EF</td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>

 <td><span title='Read coprocessor register to ARM register'>MRC</span></td>
</tr>
<tr>
 <td class='bit'>F0</td>
 <td rowspan='16' colspan='16'><span title='Software interrupt (enter supervisor mode)'>SWI</span></td>
</tr>
<tr>
 <td class='bit'>F1</td>
</tr>
<tr>
 <td class='bit'>F2</td>
</tr>
<tr>
 <td class='bit'>F3</td>
</tr>
<tr>
 <td class='bit'>F4</td>
</tr>
<tr>
 <td class='bit'>F5</td>
</tr>
<tr>
 <td class='bit'>F6</td>
</tr>
<tr>
 <td class='bit'>F7</td>
</tr>
<tr>
 <td class='bit'>F8</td>
</tr>
<tr>
 <td class='bit'>F9</td>
</tr>
<tr>
 <td class='bit'>FA</td>
</tr>
<tr>
 <td class='bit'>FB</td>
</tr>
<tr>
 <td class='bit'>FC</td>
</tr>
<tr>
 <td class='bit'>FD</td>
</tr>
<tr>
 <td class='bit'>FE</td>
</tr>
<tr>
 <td class='bit'>FF</td>
</tr>
   </tbody>
  </table>
  <table>
   <caption>Table 2. Thumb Opcode Map.</caption>
   <thead>
    <tr>
     <th rowspan='2'>Bits<br>15-12</th>
     <th colspan='16'>Bits 11-8</th>
    </tr>
    <tr>
     <th>0</th><th>1</th><th>2</th><th>3</th>
     <th>4</th><th>5</th><th>6</th><th>7</th>
     <th>8</th><th>9</th><th>A</th><th>B</th>
     <th>C</th><th>D</th><th>E</th><th>F</th>
    </tr>
   </thead>
   <tbody>
<tr>
 <td class='bit'>0</td>
 <td colspan='8'><span title='Logical shift-left register'>LSL</span> <span title='Immediate value'>imm</span></td>
 <td colspan='8'><span title='Logical shift-right register'>LSR</span> <span title='Immediate value'>imm</span></td>
</tr>
<tr>
 <td class='bit'>1</td>
 <td colspan='8'><span title='Arithmetic shift-right register'>ASR</span> <span title='Immediate value'>imm</span></td>
 <td colspan='2'><span title='Add to register'>ADD</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Subtract from register'>SUB</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Add to register'>ADD</span> <span title='3-bit immediate offset'>imm3</span></td>
 <td colspan='2'><span title='Subtract from register'>SUB</span> <span title='3-bit immediate offset'>imm3</span></td>
</tr>
<tr>
 <td class='bit'>2</td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r0'>i8r0</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r1'>i8r1</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r2'>i8r2</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r3'>i8r3</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r4'>i8r4</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r5'>i8r5</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r6'>i8r6</span></td>
 <td><span title='Move value to a register'>MOV</span> <span title='8-bit immediate offset, using r7'>i8r7</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r0'>i8r0</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r1'>i8r1</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r2'>i8r2</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r3'>i8r3</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r4'>i8r4</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r5'>i8r5</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r6'>i8r6</span></td>
 <td><span title='Compare register to value (Subtract)'>CMP</span> <span title='8-bit immediate offset, using r7'>i8r7</span></td>
</tr>
<tr>
 <td class='bit'>3</td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r0'>i8r0</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r1'>i8r1</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r2'>i8r2</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r3'>i8r3</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r4'>i8r4</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r5'>i8r5</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r6'>i8r6</span></td>
 <td><span title='Add to register'>ADD</span> <span title='8-bit immediate offset, using r7'>i8r7</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r0'>i8r0</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r1'>i8r1</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r2'>i8r2</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r3'>i8r3</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r4'>i8r4</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r5'>i8r5</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r6'>i8r6</span></td>
 <td><span title='Subtract from register'>SUB</span> <span title='8-bit immediate offset, using r7'>i8r7</span></td>
</tr>
<tr>
 <td class='bit'>4</td>
 <td><span title='Thumb data processing'>DP</span> <span title='Instruction group 1'>g1</span></td>
 <td><span title='Thumb data processing'>DP</span> <span title='Instruction group 2'>g2</span></td>
 <td><span title='Thumb data processing'>DP</span> <span title='Instruction group 3'>g3</span></td>
 <td><span title='Thumb data processing'>DP</span> <span title='Instruction group 4'>g4</span></td>
 <td><span title='Add registers, select from all 16'>ADDH</span></td>
 <td><span title='Compare registers, select from all 16'>CMPH</span></td>
 <td><span title='Move to a register, select from all 16'>MOVH</span></td>
 <td><span title='Branch and switch execution modes'>BX</span> <span title='Register offset'>reg</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r0'>r0</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r1'>r1</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r2'>r2</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r3'>r3</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r4'>r4</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r5'>r5</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r6'>r6</span></td>
 <td><span title='r15-relative load word'>LDRPC</span> <span title='Using r7'>r7</span></td>
</tr>
<tr>
 <td class='bit'>5</td>
 <td colspan='2'><span title='Store word'>STR</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Store halfword'>STRH</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Store byte'>STRB</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Load signed byte'>LDRSB</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Load word'>LDR</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Load halfword'>LDRH</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Load byte'>LDRB</span> <span title='Register offset'>reg</span></td>
 <td colspan='2'><span title='Load signed halfword'>LDRSH</span> <span title='Register offset'>reg</span></td>
</tr>
<tr>
 <td class='bit'>6</td>
 <td colspan='8'><span title='Store word'>STR</span> <span title='5-bit immediate offset'>imm5</span></td>
 <td colspan='8'><span title='Load word'>LDR</span> <span title='5-bit immediate offset'>imm5</span></td>
</tr>
<tr>
 <td class='bit'>7</td>
 <td colspan='8'><span title='Store byte'>STRB</span> <span title='5-bit immediate offset'>imm5</span></td>
 <td colspan='8'><span title='Load byte'>LDRB</span> <span title='5-bit immediate offset'>imm5</span></td>
</tr>
<tr>
 <td class='bit'>8</td>
 <td colspan='8'><span title='Store halfword'>STRH</span> <span title='5-bit immediate offset'>imm5</span></td>
 <td colspan='8'><span title='Load halfword'>LDRH</span> <span title='5-bit immediate offset'>imm5</span></td>
</tr>
<tr>
 <td class='bit'>9</td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r0'>r0</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r1'>r1</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r2'>r2</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r3'>r3</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r4'>r4</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r5'>r5</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r6'>r6</span></td>
 <td><span title='r13-relative store word'>STRSP</span> <span title='Using r7'>r7</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r0'>r0</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r1'>r1</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r2'>r2</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r3'>r3</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r4'>r4</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r5'>r5</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r6'>r6</span></td>
 <td><span title='r13-relative load word'>LDRSP</span> <span title='Using r7'>r7</span></td>
</tr>
<tr>
 <td class='bit'>A</td>
 <td><span title=''>ADDPC</span> <span title='Using r0'>r0</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r1'>r1</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r2'>r2</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r3'>r3</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r4'>r4</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r5'>r5</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r6'>r6</span></td>
 <td><span title=''>ADDPC</span> <span title='Using r7'>r7</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r0'>r0</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r1'>r1</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r2'>r2</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r3'>r3</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r4'>r4</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r5'>r5</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r6'>r6</span></td>
 <td><span title=''>ADDSP</span> <span title='Using r7'>r7</span></td>
</tr>
<tr>
 <td class='bit'>B</td>
 <td><span title=''>ADDSP</span> <span title='7-bit immediate offset'>imm7</span></td>
 <td class='und' colspan='3'></td>
 <td><span title='Store multiple words to memory (STMDB equivalent)'>PUSH</span></td>
 <td><span title='Store multiple words to memory (STMDB equivalent)'>PUSH</span> <span title='Include r14'>lr</span></td>
 <td class='und' colspan='6'></td>
 <td><span title='Load multiple words from memory (LDMIA equivalent)'>POP</span></td>
 <td><span title='Load multiple words from memory (LDMIA equivalent)'>POP</span> <span title='Include r15'>pc</span></td>
 <td class='arm9'><span title='Software breakpoint'>BKPT</span></td>
 <td class='und'></td>
</tr>
<tr>
 <td class='bit'>C</td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r0'>r0</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r1'>r1</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r2'>r2</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r3'>r3</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r4'>r4</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r5'>r5</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r6'>r6</span></td>
 <td><span title='Store multiple words, increment after'>STMIA</span> <span title='Using r7'>r7</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r0'>r0</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r1'>r1</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r2'>r2</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r3'>r3</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r4'>r4</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r5'>r5</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r6'>r6</span></td>
 <td><span title='Load multiple words, increment after'>LDMIA</span> <span title='Using r7'>r7</span></td>
</tr>
<tr>
 <td class='bit'>D</td>
 <td><span title='Branch if zero flag set'>BEQ</span></td>
 <td><span title='Branch if zero flag clear'>BNE</span></td>
 <td><span title='Branch if carry flag set'>BCS</span></td>
 <td><span title='Branch if carry flag clear'>BCC</span></td>
 <td><span title='Branch if negative flag set'>BMI</span></td>
 <td><span title='Branch if negative flag clear'>BPL</span></td>
 <td><span title='Branch if overflow flag set'>BVS</span></td>
 <td><span title='Branch if overflow flag clear'>BVC</span></td>
 <td><span title='Branch if higher (unsigned)'>BHI</span></td>
 <td><span title='Branch if lower or the same (unsigned)'>BLS</span></td>
 <td><span title='Branch if greater than or equal to'>BGE</span></td>
 <td><span title='Branch if less than'>BLT</span></td>
 <td><span title='Branch if greater than'>BGT</span></td>
 <td><span title='Branch if less than or equal to'>BLE</span></td>
 <td class='und'></td>
 <td><span title='Software interrupt (enter supervisor mode)'>SWI</span></td>
</tr>
<tr>
 <td class='bit'>E</td>
 <td colspan='8'><span title='Branch'>B</span></td>
 <td class='arm9' colspan='8'><span title='Branch, link and switch execution modes '>BLX</span> <span title='Two-instruction branch, low 11 bits of offset'>off</span></td>
</tr>
<tr>
 <td class='bit'>F</td>
 <td colspan='8'><span title='Branch and link'>BL</span> <span title='Two-instruction branch, high 11 bits of offset'>setup</span></td>
 <td colspan='8'><span title='Branch and link'>BL</span> <span title='Two-instruction branch, low 11 bits of offset'>off</span></td>
</tr>
   </tbody>
  </table>
  <table>
   <caption>Table 2A. Thumb Opcode Map - Register/Register Data Processing.</caption>
   <thead>
    <tr>
     <th rowspan='2'>Bits<br>9-8</th>
     <th colspan='4'>Bits 7-6</th>
    </tr>
    <tr>
     <th>0</th><th>1</th><th>2</th><th>3</th>
    </tr>
   </thead>
   <tbody>
<tr>
 <td class='bit'>0</td>
 <td><span title='Logical And'>AND</span></td>
 <td><span title='Logical Exclusive-or'>EOR</span></td>
 <td><span title='Logical Left-shift'>LSL</span></td>
 <td><span title='Logical Right-shift'>LSR</span></td>
</tr>
<tr>
 <td class='bit'>1</td>
 <td><span title='Arithmetic Right-shift'>ASR</span></td>
 <td><span title='Add'>ADD</span></td>
 <td><span title='Subtract'>SUB</span></td>
 <td><span title='Rotate right'>ROR</span></td>
</tr>
<tr>
 <td class='bit'>2</td>
 <td><span title='Test Bits (Logical And)'>TST</span></td>
 <td><span title='Negate (Subtract from zero)'>NEG</span></td>
 <td><span title='Compare (Subtract)'>CMP</span></td>
 <td><span title='Compare negative (Add)'>CMN</span></td>
</tr>
<tr>
 <td class='bit'>3</td>
 <td><span title='Logical Or'>ORR</span></td>
 <td><span title='Multiply'>MUL</span></td>
 <td><span title='Bit Clear (NAND)'>BIC</span></td>
 <td><span title='Move negative (NOT)'>MVN</span></td>
</tr>
   </tbody>
  </table>
  </div>
 ]]></content>
</entry>
<entry>
 <title type="html">Tetris in Vanilla JavaScript</title>
 <link href="https://imrannazar.com/articles/js-tetris" rel="alternate" type="text/html" title="Tetris in Vanilla JavaScript" />
 <id>https://imrannazar.com/articles/js-tetris</id>
 <summary>It&#039;s often said by some that JavaScript isn&#039;t a real programming language, that it can&#039;t provide the full range of development possibilities that a more complex language would be able to give. It&#039;s quite easy to prove this argument wrong: JavaScript is a full-blown language, with some very interesting features that conventional languages fail to bring to the table. It&#039;s also quite easy to write programs with, and I put this example together to prove the point: an implementation of Tetris in HTML and JavaScript, playable right in your browser.</summary>
 <category term="Articles" />
 <published>Thu, 04 Oct 2007 19:27:49 +0000</published>
 <content type="text/html"><![CDATA[
     <style>
ul {
  list-style: square inside;
}

p#score {
  margin: 10px 20px 0px 10px;
  float: left;
  display: inline;
  width: 160px;
}

p#score #pause {
  display: inline;
  float: right;
}

#tetris {
  width: 160px;
  height: 320px;
  background: black;
  margin: 0px 20px 10px 10px;
  color: white;
  position: relative;
  overflow: hidden;
  float: left;
  clear: left;
  display: inline;
}

#tetris div {
  width: 14px;
  height: 14px;
  line-height: 1px;
  font-size: 1px;
  position: absolute;
  border-style: solid;
  border-width: 1px;
}

.block1 { background:#888; border-left-color:#ccc; border-top-color:#ccc; border-bottom-color:#444; border-right-color:#444; }
.block2 { background:#800; border-left-color:#c00; border-top-color:#c00; border-bottom-color:#400; border-right-color:#400; }
.block3 { background:#080; border-left-color:#0c0; border-top-color:#0c0; border-bottom-color:#040; border-right-color:#040; }
.block4 { background:#008; border-left-color:#00c; border-top-color:#00c; border-bottom-color:#004; border-right-color:#004; }
.block5 { background:#880; border-left-color:#cc0; border-top-color:#cc0; border-bottom-color:#440; border-right-color:#440; }
.block6 { background:#088; border-left-color:#0cc; border-top-color:#0cc; border-bottom-color:#044; border-right-color:#044; }
.block7 { background:#808; border-left-color:#c0c; border-top-color:#c0c; border-bottom-color:#404; border-right-color:#404; }

.space {
  background: black;
  border: 0px solid black;
}
  </style>
  <script type='text/javascript' src='/content/files/tetris.js'></script>
  <p id='score'><a id='pause' href='#'>Pause</a><span></span></p>
  <div id='tetris'>
  </div>
  <p>This page demonstrates an implementation of the classic game 'Tetris',
  in JavaScript. The major purpose is to demonstrate how addition to and
  manipulation of the DOM can be performed easily: the Tetris display
  consists of two hundred DIVs in a 10x20 grid, which are given different
  class names to represent the blocks in the well.</p>
  <p>JavaScript also makes it easy to retrieve events from the keyboard;
  the 'window' object provides an 'event' subsystem, which in combination
  with the setting of event handlers for the keyboard allows the script
  to capture and process keys. This implementation of Tetris uses four
  keys:</p>
  <ul>
   <li>Left: move the current piece left one block</li>
   <li>Right: move the current piece right one block</li>
   <li>Up: Rotate the piece by 90 degrees</li>
   <li>Down: Push the piece down quickly</li>
  </ul>
  <p>You're free to take a look at the source, and explore the game for
  any bugs which may exist (I already know of a couple). Enjoy.</p>
  <div style='clear:both'></div>
 ]]></content>
</entry>
<entry>
 <title type="html">Running a Windows Partition in VMWare</title>
 <link href="https://imrannazar.com/articles/windows-in-vmware" rel="alternate" type="text/html" title="Running a Windows Partition in VMWare" />
 <id>https://imrannazar.com/articles/windows-in-vmware</id>
 <summary>Virtualisation of operating systems is a big trend at the moment: running multiple servers on one physical box allows a hosting company to save space and power costs, and running different operating systems lets a Web developer test their work on various browsers and hosts. The problem with setting up a virtual machine is the loss of disk space on the host, to hold a disk image for the guest; what if you&#039;ve already got an installation on another partition? This article shows how to use that physical installation in VMware, using the example of Linux as the host and Windows XP as the guest.</summary>
 <category term="Articles" />
 <published>Sat, 20 Jan 2007 21:54:02 +0000</published>
 <content type="text/html"><![CDATA[
   <p>I have my system partitioned into two: one part of the hard drive hosts
a Windows XP partition, and the other runs Gentoo Linux. About a month ago,
I was just about tired of having to reboot to switch between the two, so
I decided to set up a VM for Windows.</p>
<p>There was, however, a snag to this: I wanted to use the existing Windows
installation, because I'd tuned it up and installed the software I always
use. I expressly didn't want a virtual disk image duplicating my Windows
drive, since I didn't have the space for that. So, that was the task:
running the Windows partition in a VM.</p>
<p>I hunted around the 'Net, and found surprisingly little information on
this: the procedure I finally threw together was sourced from many
disparate places. So, in one place, I've put together the steps you'll
need to take in order to get a Windows partition running inside a VM.</p>
<h2>What you'll need</h2>
<p>You'll need a few tools in order to pull the information you need, and
to run the finished VM:</p>
<dl>
 <dt>VMware Player:</dt>
 <dd>The easiest way to get a finished VM running; all you need to do is
 point the VM information file at <code>vmplayer</code>, and you're good
 to go.</dd>
 <dt>VMware kernel modules for Linux:</dt>
 <dd>All VMware products on Linux use kernel modules to get monitoring and
 networking functionality working, so you'll need those.</dd>
 <dt>A text editor:</dt>
 <dd>We'll be doing some hacking of configuration and VM information files,
 which means your favourite text editor.</dd>
 <dt>GNU Parted:</dt>
 <dd>In order for us to tell VMware about the hard disk, we need to know a
 few things about the disk; we'll also be doing a little hacking of the
 partition table. Parted allows us to do this from the command line, and
 quite easily too.</dd>
</dl>
<p>On a Gentoo Linux installation, you can get the software you need on the
Linux side from the following command (on other distributions, check your
associated documentation):</p>
<samp>
 <pre>emerge vmware-player vmware-modules parted</pre>
</samp>
<h2>Stage 1: Setting up a virtual hard disk</h2>
<p>VMware needs a virtual disk descriptor file, telling it how the disk is
set up and structured. So, dump the following into a file called
<code>WindowsXP.vmdk</code>:</p>
<samp>
 <h3>Disk description: WindowsXP.vmdk</h3>
 <pre># Disk DescriptorFile
version=1
CID=9428f535
parentCID=ffffffff
createType="fullDevice"

# Extent description
RW 63 FLAT "WindowsXP.mbr" 0
RW <var>23579072</var> FLAT "<var>/dev/hda</var>" 63

# The Disk Data Base 
#DDB

ddb.toolsVersion = "6530"
ddb.adapterType = "ide"
ddb.virtualHWVersion = "4"
ddb.geometry.sectors = "<var>63</var>"
ddb.geometry.heads = "<var>240</var>"
ddb.geometry.cylinders = "<var>1559</var>"
 </pre>
</samp>
<p>The values highlighted in red are ones you'll need to change, depending on
the characteristics of your hard disk: they describe my disk quite well.</p>
<p>Now you can fire up Parted against the disk you want to use. If you have
Windows on one hard disk and Linux on another, use the Windows disk in the
command below, otherwise just use the disk device containing the Windows
partition.</p>
<samp>
 <h3>Fetching disk information: Parted output</h3>
 <pre># <s>parted /dev/hda</s>
GNU Parted 1.7.1
Using /dev/hda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) <s>unit s</s>                                                           
(parted) <s>print</s>                                                            

Disk /dev/hda: <var>23579135</var>s
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End        Size       Type     File system  Flags
 1      63s        9223199s   9223137s   primary  ntfs              
 2      9223200s   22679999s  13456800s  primary  ext3         boot 
 3      22680000s  23572079s  892080s    primary  linux-swap         

(parted) <s>unit cyl</s>                                                         
(parted) <s>print</s>                                                            

Disk /dev/hda: 1559cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: <var>1559,240,63</var>.  Each cylinder is 7741kB.
Partition Table: msdos

Number  Start    End      Size    Type     File system  Flags
 1      0cyl     609cyl   609cyl  primary  ntfs              
 2      610cyl   1499cyl  890cyl  primary  ext3         boot 
 3      1500cyl  1558cyl  59cyl   primary  linux-swap        </pre>
</samp>
<p>Note the <code>unit s</code> command, which tells Parted to print out its
values in terms of disk sectors: we'll be using these values in the VMDK file.
Also note the second <code>unit</code> command, to provide the values in
cylinders; that allows us to fetch the disk geometry in CHS format.</p>
<p>The values in red are the ones we'll be using. But not so fast; before you
plug the values in, we'll need to do some calculation. Instead of using the
hard disk's standard boot sector, which allows you to boot Windows or Linux,
we ideally want the VM to boot only Windows. We'll be doing that by telling
the Windows partition to boot, ignoring the Linux boot menu, and then making
a copy of that bootsector for the VM to use.</p>
<p>All that means we need two lines in the VMDK, as shown above: a line for
the bootsector copy, starting at sector 0 and stretching for 63 sectors; and
the rest of the hard disk, starting at sector 63. And that means a little
calculation: the value in the VMDK for the size of the disk is 63 less than
the actual disk.</p>
<samp>
 <h3>Size of the virtual disk: Subtracting the MBR</h3>
 <pre>23579135 - 63 = 23579072</pre>
</samp>
<p>Note that this is the value I've got in my VMDK, shown above.</p>
<p>I mentioned above that we'll be using a copy of the disk's bootsector for
the VM, with Windows set to boot. We'll need to set that up first:</p>
<samp>
 <h3>Setting Windows to boot: Parted output</h3>
 <pre>(parted) <s>set 1 boot on</s>
(parted) <s>print</s>                                                            

Disk /dev/hda: 1559cyl
Sector size (logical/physical): 512B/512B
BIOS cylinder,head,sector geometry: 1559,240,63.  Each cylinder is 7741kB.
Partition Table: msdos

Number  Start    End      Size    Type     File system  Flags
 1      0cyl     609cyl   609cyl  primary  ntfs         boot     
 2      610cyl   1499cyl  890cyl  primary  ext3         
 3      1500cyl  1558cyl  59cyl   primary  linux-swap        

(parted) <s>quit</s>
#</pre>
</samp>
<p>Now to make a copy of the bootsector, using the infamous <code>dd</code>
utility:</p>
<samp>
 <h3>Copying the bootsector</h3>
 <pre># <s>dd if=/dev/hda of=WindowsXP.mbr bs=512 count=63</s>
63+0 sectors in
63+0 sectors out
#</pre>
</samp>
<h2>Stage 2: The VMware information file</h2>
<p>Once the VMDK is set up, we need to tell VMware what exactly it'll be booting,
and which hardware to emulate. This is done by the information file, which in
this case is <code>WindowsXP.vmx</code>:</p>
<samp>
 <h3>The information file: WindowsXP.vmx</h3>
 <pre>config.version = "8"
virtualHW.version = "4"

uuid.location = "56 4d 56 4a 7b d7 4c 30-f5 80 d6 8b c4 59 aa eb"
uuid.bios = "56 4d 56 4a 7b d7 4c 30-f5 80 d6 8b c4 59 aa eb"

uuid.action = "create"
checkpoint.vmState = ""

displayName = "Windows XP Professional"
annotation = ""
guestinfo.vmware.product.long = ""
guestinfo.vmware.product.url = ""

guestOS = "winxppro"
numvcpus = "1"
memsize = "<var>128</var>"
paevm = "FALSE"
sched.mem.pshare.enable = "TRUE"
MemAllowAutoScaleDown = "FALSE"

MemTrimRate = "-1"

nvram = "WindowsXP.nvram"

mks.enable3d = "FALSE"
vmmouse.present = "FALSE"
vmmouse.fileName = "auto detect"

tools.syncTime = "TRUE"
tools.remindinstall = "FALSE"

isolation.tools.hgfs.disable = "FALSE"
isolation.tools.dnd.disable = "FALSE"
isolation.tools.copy.enable = "TRUE"
isolation.tools.paste.enabled = "TRUE"
gui.restricted = "FALSE"

ethernet0.present = "TRUE"
ethernet0.connectionType = "nat"
ethernet0.addressType = "generated"
ethernet0.generatedAddress = "00:0c:29:59:aa:eb"
ethernet0.generatedAddressOffset = "0"

usb.present = "TRUE"
usb.generic.autoconnect = "TRUE"

sound.present = "TRUE"
sound.virtualdev = "sb16"

ide0:0.present = "TRUE"
ide0:0.fileName = "WindowsXP.vmdk"
ide0:0.mode = "independent-persistent"
ide0:0.deviceType = "rawDisk"
ide0:0.redo = ""
ide0:0.writeThrough = "FALSE"
ide0:0.startConnected = "TRUE"

ide1:0.present = "TRUE"
ide1:0.fileName = "<var>/dev/cdrom</var>"
ide1:0.deviceType = "atapi-cdrom"
ide1:0.writeThrough = "FALSE"
ide1:0.startConnected = "TRUE"

floppy0.present = "TRUE"
floppy0.fileName = "/dev/fd0"
floppy0.startConnected = "TRUE"

serial0.present = "FALSE"
serial1.present = "FALSE"
parallel0.present = "FALSE"</pre>
</samp>
<p>I've highlighted a couple of values which you might want to change: the
location of the CD drive in the device tree, and the amount of memory you
want to allocate to the VM.</p>
<h2>Stage 3: Setting up Windows</h2>
<p>We're not done yet; the Linux side of setting up the VM is running, but
we now need to tell Windows that it'll be booting into a VM. The problem
is rooted in the fact that the VM's hardware is different to your physical
computer; thus, we need to add a hardware profile to the Windows partition.</p>
<p>We can also take this opportunity to test that the Windows partition
boots up immediately, without a boot menu in the way. Reboot, and if the
boot process doesn't run straight to Windows, you may need to tweak the
partition boot settings and recreate the bootsector copy.</p>
<p>Once you're booted into Windows, pull open the System properties
(Control Panel -&gt; System, or My Computer (rightclick)-&gt; Properties):</p>
<figure>
 <img src='/content/img/vmware-windows-system-properties.png' alt='System properties'>
 <img src='/content/img/vmware-windows-hardware-profiles.png' alt='Hardware profiles'>
</figure>
<p>The default setup for this Hardware Profiles display is one profile,
called "Default". Click on "Copy", to create a new profile, and call that one
"VMware", then move it to the top of the list with the arrow buttons. You can
see the settings I use in the image above, and we'll see exactly what that
means for the Windows boot process in a little while.</p>
<p>While you have the System Properties open, pull open the Driver Signing
properties, and set the value of what action Windows should take to "Ignore";
this allows any drivers to be installed automatically if devices are picked
up by Windows.</p>
<p>This is also a good time to set up a helper script, which will install the
VMware Tools: a set of drivers for the VMware emulated devices, and some services
to help the Windows VM along. This could be done after the VM is set up and
running, but I had issues with that, as detailed later. I've decided to put it
here in stage 3, to catch the problem before it begins.</p>
<p>The VMware tools are provided by VMware as a CD ISO image, buried within the
VMware Workstation software. It's relatively easy to find: first of all, download
Workstation from VMware, or any Linux mirror (I've given a sample mirror below):</p>
<p><a href='http://ftp.snt.utwente.nl/pub/os/linux/gentoo/distfiles/VMware-workstation-5.5.3-34685.tar.gz'>http://ftp.snt.utwente.nl/pub/os/linux/gentoo/distfiles/VMware-workstation-5.5.3-34685.tar.gz</a></p>
<p>Once you've got the file, extract its contents (you may need third-party tools
to do this in Windows), and look for a file called <code>windows.iso</code>; this
is the Tools CD image. If you feel like wasting a CD, burn the image to one, or
you can mount the image as a drive using Daemon Tools or similar software.</p>
<p>When you can see the contents of the image, copy the files to your hard disk,
in a directory called <code>C:\VMTools</code> or something similar. Then dump
the following into a <code>.cmd</code> file:</p>
<samp>
 <h3>VMware Tools install helper: C:\VMTools\ToolsHelper.cmd</h3>
 <pre>if exist C:\VMTools\ToolsHelperLock.txt msiexec -i "C:\VMTools\VMware Tools.msi" /qn
if exist C:\VMTools\ToolsHelperLock.txt shutdown -r -f -t 30
del C:\VMTools\ToolsHelperLock.txt</pre>
</samp>
<p>Also, put a small message (any you like) into <code>ToolsHelperLock.txt</code>
in the same directory. The lock file will be used by the helper script to work out if
it needs to reboot. Once you've done this, add the script to your Start Menu's
Startup folder, and you'll be away.</p>
<p>Log yourself out of Windows and reboot; that should be the last time it needs to be
started physically. Boot yourself into Linux; it's time to test this thing.</p>
<h2>Stage 4: Virtual Windows</h2>
<p>When you fire up the VM, it should now automatically pick up the Windows
partition, and begin booting it. The presence of two hardware profiles means
that Windows will ask which one you wish to use:</p>
<figure><img src='/content/img/vmware-windows-boot-select.png' alt='Boot-time hardware profile selection'></figure>
<p>Pick the VMware profile, and Windows should boot, into a very minimal VGA-colour
mode: it doesn't have the drivers for the "VMware SVGA" yet. At this point, the
helper script should kick in, install the VMware tools, and then reboot the VM.
Make sure to remove the helper script from your Startup folder upon the next reboot;
even though it won't run, it'll still flash a Command-Prompt window up for a short
while.</p>
<h2>Snags: Getting the network running</h2>
<p>I mentioned earlier that I had a problem with my keyboard and mouse not being
detected by Windows in the VM, thus bringing about the helper script to allow the
VMware tools to install the requisite drivers. I did have another issue with the
VM, and that was getting it to talk to the outside world.</p>
<p>Initially, I set the VM's network card to a "bridged" type, allowing it to
reside on the same network as the host machine; this usually works fine. In the
case of a laptop with wireless, however, it didn't so much: no communication.
After some experimentation, I resorted to the NAT method: one network that the
host computer sits on, and another between the host and VM. This also involves
a bit of <code>iptables</code> trickery, so I'm putting it in as a part of this
guide.</p>
<p>In my case, the normal wireless network resides on <code>192.168.1.0/24</code>,
so I decided to put the virtual network at <code>192.168.58.0/24</code>. This 
means the host gets an address of <code>192.168.58.1</code> on the NAT network,
and the VM's network connection gets a static IP of <code>192.168.58.2</code>;
it also means the following changes to the Linux host's configuration:</p>
<samp>
 <h3>Allowing IP forwarding: /etc/sysctl.conf</h3>
 <pre>net.ipv4.ip_forward = 1</pre>
 <h3>Initialising iptables NAT: /etc/conf.d/local.start</h3>
 <pre>ifconfig ra0:1 192.168.1.252
iptables -t nat -A PREROUTING -i ra0 -d 192.168.1.252 -j DNAT --to-destination 192.168.58.2
iptables -t nat -A POSTROUTING -o ra0 -s 192.168.58.2 -j SNAT --to-source 192.168.1.252
iptables -A INPUT -i ra0 -d 192.168.1.252 -p tcp -j ACCEPT
iptables -A INPUT -i ra0 -d 192.168.1.252 -p udp -j ACCEPT
iptables -A INPUT -i ra0 -d 192.168.1.252 -p icmp -j ACCEPT</pre>
</samp>
<p>Note how the wireless interface <code>ra0</code> has had a virtual interface
added, dedicated to the transfer of traffic for the virtual machine NAT. The
particular configuration files you need to change may differ depending on the
distribution; the changes above are from my Gentoo system.</p>
<h2>In the End: Windows in a VM</h2>
<p>After all's said and done, you should have something like this:</p>
<figure><img src='/content/img/vmware-windows-final.png' alt='Windows in a VM'></figure>
<p>Let me know if you get it working, or if you want to shout at me about something.</p>
<p><a href='mailto:tf@oopsilon.com'>Imran Nazar (tf@oopsilon.com)</a>
 ]]></content>
</entry>
<entry>
 <title type="html">Trainfuck: Networking Extensions for Brainfuck</title>
 <link href="https://imrannazar.com/articles/trainfuck" rel="alternate" type="text/html" title="Trainfuck: Networking Extensions for Brainfuck" />
 <id>https://imrannazar.com/articles/trainfuck</id>
 <summary>One of the most widely-known esoteric programming languages is Brainf*ck, which attempts to break computing operations down into the simplest possible steps: just eight operations are provided, along with a small buffer of memory to work with. The problem with Brainf*ck is that it only provides the most basic I/O, interfacing with the console. Trainf*ck is an extension of the language, which endeavours to provide the ability to read and write files, and communicate over a TCP/IP network.</summary>
 <category term="Articles" />
 <published>Tue, 26 Sep 2006 15:45:23 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The Trainf*ck project is an attempt to extend the capabilities of the
esoteric Brainf*ck language to include viable outside interaction, including
file operations and TCP networking. In this respect, the goals of the
project are similar to those of Brainf*ck++; Trainf*ck differs in the
implementation of these goals.</p>
<p>As is documented elsewhere, Brainf*ck has eight simple operations, which
may act on a data buffer of a given size. Trainf*ck extends the list of
operations to eighteen, while leaving the other aspects as is. The new
instructions are as follows (P refers to the current address in the data
space).</p>
<h2>Instructions</h2>
<dl>
 <dt>File I/O</dt>
 <dd>
  <ul>
   <li><code>#</code> - Open or close a file. Takes a null-terminated filename string
   starting at P. If called again, closes the currently open file; no
   parameter required for close.</li>
   <li><code>;</code> - Read a byte from file. Saves the byte to P.</li>
   <li><code>:</code> - Write a byte to file. Fetches the byte from P, and writes.</li>
   <li><code>(</code> - Rewind one byte. Modifies P: 0 if start of file was reached,
   1 otherwise.</li>
   <li><code>)</code> - Move forward a byte. Modifies P: 0 if end of file was reached,
   1 otherwise.</li>
  </ul>
 </dd>
 <dt>Networking</dt>
 <dd>
  <ul>
   <li><code>%</code> - Connect to an address/port. Takes two parameters: big-endian
   IPv4 address starting at P, and big-endian TCP port number starting at
   P+4. If called again, closes currently open socket; no parameters
   required.</li>
   <li><code>$</code> - Listen on an address/port. Takes address and port as detailed
   for %. If called again, closes currently open socket; no parameters
   required.</li>
   <li><code>@</code> - Accepts an incoming connection. If called again, closes the
   currently accepted connection.</li>
   <li><code>`</code> - Receive a byte from the network stream. Saves the byte to P,
   or zero if connection was closed.</li>
   <li><code>'</code> - Send a byte. Fetches the byte from P, and sends.</li>
  </ul>
 </dd>
</dl>
<h2>Examples</h2>
<p>The canonical "Hello World" example as written in Brainf*ck will run under
Trainf*ck exactly as it does under Brainf*ck. An example implementation follows,
which prints out "Hello World!".</p>
<samp>
 <h2>Trainf*ck sample: Hello World</h2>
 <pre>&gt;+++++++++[&lt;++++++++&gt;-]&lt;.&gt;
+++++++[&lt;++++&gt;-]&lt;+.+++++++..+++.&gt;&gt;&gt;++++++++[&lt;++++&gt;-]&lt;.
&gt;&gt;&gt;++++++++++[&lt;+++++++++&gt;-]&lt;---.&lt;&lt;&lt;&lt;.+++.------.--------.&gt;&gt;+.</pre>
</samp>
<p>A simple example demonstrating Trainf*ck's file handling capabilities is that
of finding the size of a file. The following example calculates the size of the
file "abcd", and outputs it as a character code value. The caveat with this
simple example is that it will wrap the counted value after 255.</p>
<samp>
 <h2>Trainf*ck sample: File size</h2>
 <pre>&gt;++++++++++++++++[&lt;++++++&gt;-]&lt;    Generate backtick in 0
[&gt;+&gt;+&gt;+&gt;+&lt;&lt;&lt;&lt;-]                  Copy 4 times
&gt;+&gt;++&gt;+++&gt;++++                   Generate "abcd"
&lt;&lt;&lt;#&lt;+                           Open file and init counter
&gt;[&lt;+:&gt;)]                         Count up file size
&lt;.#                              Output file size and close</pre>
</samp>
<p>Networking is where Trainf*ck's capabilities shine: the language provides
the ability to perform networking tasks easily and efficiently. The following
example is an implementation of an 'echo' daemon, which listens on port 20480
and repeats any text sent to it.</p>
<samp>
 <h2>Trainf*ck sample: Echo daemon</h2>
 <pre>&gt;&gt;&gt;                           Address 0x00000000
&gt;&gt;++++++++[&lt;++++++++++&gt;-]     Port 0x5000
&lt;&lt;&lt;&lt;&lt;$                        Listen
+[                            Continual loop
  @                           Accept a connection
  [`']                        Loop echoing
  @                           Close connection
+]                            Continue endless loop</pre>
</samp>
<h2>Implementation</h2>
<p>The Trainf*ck interpreter is written in C++, and has been tested working
on Linux. The code has been designed with portability in mind, and as such
there should be no major issues with execution on any system.</p>
<p>The interpreter is currently incomplete, with the functionality of
keyboard input being missing. It is anticipated that this will be added
at a later date.</p>
<p>You can obtain the interpreter and the sample files detailed above from
the following address.</p>
<p><a href='http://oopsilon.com/software/Trainf_ck.tar.gz'>http://oopsilon.com/software/Trainf_ck.tar.gz</a></p>

 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Hideout</title>
 <link href="https://imrannazar.com/scifi/hideout" rel="alternate" type="text/html" title="Sci-fi Shorts: Hideout" />
 <id>https://imrannazar.com/scifi/hideout</id>
 <summary>Two hackers must destroy their evidence when a team of armed police show up outside their apartment. Screenplay.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:49:30 +0000</published>
 <content type="text/html"><![CDATA[
   <samp>
<pre>
OPEN: A display of a complex graphical shape, with numbers scrolling down one
side. A phone rings.

		ABDUL
	Yeah?

		CHRIS (phone)
	We gotta talk about these test runs.

		ABDUL
	Yeah, I'm in the middle of one right now. Can't we talk a little
	later?

		CHRIS
	Seriously, I gotta talk to you.

		ABDUL
	(sighs) Alright, where are you?

EXT: A shadowed street corner, looking up the road to Abdul's apartment. Abdul
and Chris are standing behind a building, at the left of screen.

		CHRIS
	I think they're onto us.

		ABDUL
	That's the second time this week, Chris. We can go to the chemist
	tomorrow if the pills aren't working any more.

		CHRIS
	Nah, I saw a van a few blocks down. They're gonna move in.

A black VW van, with lights off, rushes down the road, headed in the direction
of Abdul's apartment.

		ABDUL
	Alright. I can take care of this. You made the backups, right?

		CHRIS (holding up a data tape)
	Yeah, last night.

		ABDUL
	Put it away already, we don't want to lose all the test runs.


CUT TO: Horizontal-split screen
[TOP] Abdul pulls out a PDA, and commences to tapping on the screen.
[BOTTOM] Green text, typed:

		TEXT
	&gt; barctl --pressure 0.75

[TOP] CUT TO: INT: Abdul's apartment. A mess of computer boxes and stacks of
paper, with wires running across the floor.

PAN TO: A meter at the right side of the door, marked "Air", delineated from 0
to 2 bar, with a needle dropping to 0.75 before stopping.

[BOTTOM] Green text, typed:

		TEXT
	&gt; sendserial 0b11110000
	Connection lost

[TOP] Screen whites out.

CUT TO: EXT: Street corner

		ABDUL
	That's all four explosive lines triggered. I've dropped the air
	pressure, so the place doesn't blow out immediately. As long as they
	don't open the door, they'll be fine.

CUT TO: INT: Corridor outside Abdul's apartment. A group of six men, dressed
as a police squad, is striding down the corridor, camera tracking from in
front. They arrive at a particular door, and stop.

		OFFICER (pounding on door)
	Police! Open up!

The police officer considers for a second, then puts the palm of his hand
against the door.

		OFFICER
	Shit, it's warm. Shouldn't we get the fire service or something?

		CAPTAIN
	Fuck the fire service, we need that data. Open the damn door!

The officer joins another with a door-battering ram, and slams it against the
door twice.

CUT TO: EXT: Street corner. A few blocks behind Abdul and Chris, an apartment
block is torn by an explosion, blowing out the windows of Abdul's place. A
fireball emanates from the window, before flames start spewing. A car alarm
is triggered nearer Abdul and Chris.

		ABDUL
	They never learn.

Abdul and Chris get into Chris's car parked a few yards off, and drive away.
</pre>
</samp>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Thirteen</title>
 <link href="https://imrannazar.com/scifi/thirteen" rel="alternate" type="text/html" title="Sci-fi Shorts: Thirteen" />
 <id>https://imrannazar.com/scifi/thirteen</id>
 <summary>Terrorists use a distributed computer system to model the destruction of a continent by multiple warhead detonations. Book prologue.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:49:19 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Despite John's remonstrations, the bank of computer displays kept stolidly to
its text: "<code>13 minutes remaining</code>."</p>

<p>By all accounts, John had a simple enough job in the organisation: monitor the
computers, as they went about their task. He had been told by the previous
holder of the post that the software had an "issue" with a certain process; it
tended to get "stuck", as he put it, near the end. He'd referred to it as the
"13-minute gap", because the software always stuck when it displayed that
figure as the remaining time to completion.</p>

<p>This was John's second day, and already he'd seen the software stick twice:
once on the process last night, and again right now. Both times, it had taken
a good span of time before the computers were moving again, and it seemed that
John could do nothing to speed it up. He was a little worried that his job
seemed redundant; the setup never went wrong, since it was able to cut out any
computer units that went bad for whatever reason, and compensate for it.</p>

<p>At a wild guess, it was this compensation that the system had been doing for
the last half hour, since the displays still stubbornly read "<code>13 minutes</code>".
John decided it was time to leave the system be, and do some homework. He was
enrolled on a part-time course with the local university, and this job had
already given him ample time for study, even in his short time in the post. He
settled down with his dense book on legal theory, and set to.</p>

<p>John woke up, probably a few hours later, to find the computer room much
quieter. Obviously, in the intervening period taken by his nap, the task
allocated to the system had been completed. One of the computers had a few
sheafs of paper freshly printed in its out-tray, and he guessed he'd have to
pick those up and take them to the manager. It could wait a few more hours
though, John thought, and he did need more sleep.</p>

<hr>

<p>Abdul studied the report produced by the overnights in more detail. The first
time he'd read it, the result had looked a bit surprising. It seemed that the
task had finally hit the right nail with the right hammer.</p>

<p>It had been Moassim's idea; he tended to come up with such crazy theories,
most of which had no possible basis in fact. Abdul had listened to this one
like most that Moassim had come out with before, with a healthy dose of
speculation, but as he listened, the idea toyed with him: it seemed to gain
substance, to become a possibility. So Abdul had decided to try modelling the
plan, to plug the specifications into a computer and see what would happen.</p>

<p>The idea ran thus. The Earth's crust was a pretty robust thing, and could
take small perturbations like volcano eruptions, or climate shifts, in its
stride. This was only the case when these shocks were delivered in solitary,
however: one large eruption or one sudden cooling was no real problem, but a
prolonged series could become a problem.</p>

<p>That was the root of Moassim's theory: apply a large enough number of
significant but relatively small shocks to the crust, and it would dissolve
over a large area. Moassim saw it as the ideal strike: highly sophisticated,
beyond the comprehension of the enemy. Abdul hadn't been so sure, which was
why he'd decided to try it out mathematically first.</p>

<p>Abdul had set up a bank of computers to model the chain of detonation as per
Moassim's theory, looking for specific places and times where the chain could
best be maintained. Each night, a build process would run the tweaked
parameters, and change them a little, heading towards the ideal point: the
longest possible chain for a given amount of energy input.</p>

<p>Last night, the computer bank had hit that ideal point. Small amounts of
antimatter, placed at the coordinates indicated by the printout and then
detonated in sequence, would cause the crust of the European plate to
resonate; more detonations, as detailed by the model, would mean total
dissolution of the crust across the European area.</p>

<p>It was a vindication: the plan would work. There was just one snag: Abdul
didn't know of anyone in the world who could produce antimatter in any
quantity, and he was going to need a lot.</p>

 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Tau</title>
 <link href="https://imrannazar.com/scifi/tau" rel="alternate" type="text/html" title="Sci-fi Shorts: Tau" />
 <id>https://imrannazar.com/scifi/tau</id>
 <summary>A physics researcher is alerted to a contact who can help him realise his theories. Book prologue.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:49:05 +0000</published>
 <content type="text/html"><![CDATA[
   <p>It didn't look much like a laboratory.</p>

<p>The room was lit by fluorescent white lamps from the ceiling, a few of which
were flickering occasionally, emitting small pops as they fired on and then
went out. Shelves lined the walls, littered with sheafs of paper and
well-thumbed books, on such dry subjects as "Electromagnetic Fields at the
Subatomic Scale"; stacks of paper and books lay haphazardly at the foot of a
few of the shelves, as if abandoned.</p>

<p>In the corners lay relics of what could be old pieces of machinery, or perhaps
half-finished projects: A set of thin windows were set high in the walls,
not designed for looking out upon the world; the night made them appear as 
black slots in walls of grey. Only one area of the room was relatively clean:
a desk, up against one set of bookshelves, on which were eight identical
boxes. Wires trailed away to power sockets, and more wires connected the boxes
together. They seemed to be computers, since there was a ninth, smaller box
with a screen and keyboard attached.</p>

<p>There was a small thump at the door to the room, and then a lock turned. The
door opened, and a man stumbled in, evidently the owner of the property. He
was dressed in clothes that had probably seen better days: a plain blue
tee-shirt, fading black jeans. Indeed, he had probably seen better days, since
his face told a story of tipsiness, confirmed by the can of beer he held in
one hand. Blinking at thesudden fluorescent light, and flicked a switch to
douse the room in shade; a dim ambience filtered down from the slitted
windows, so he could at least see.</p>

<p>His boots cleared a path through the detritus on the floor, as he made his way
to the desk; setting his can down on the desk, he pulled a chair from nearby
and sat down, before hitting a key on the keyboard. The screen flashed to
life, and he again shrank away before his eyes adjusted. On the screen was
depicted some sort of process: a block on the left side was slowly
transferring itself to the right, as if through a horizontal hourglass. A
column of numbers scrolled down the far right, continuously updating with new
values as the block changed in size. The man seemed pleased with what he saw,
and took a sip from his can.</p>

<p>The phone rang. An instinctive jerk away from the source of the noise nearly
toppled the chair, before he realised that the phone was in his pocket. He
fished it out, and set to finding the Answer button.</p>

<p>"Yuh?" he blurted when he finally found it.</p>

<p>"Abdul, you sound like crap. Get online."</p>

<p>"Wha- who's that?"</p>

<p>"Just connect, yeah. I've got something you might wanna see."</p>

<p>And with that, the phone hung up. Abdul stuffed the phone back into his
pocket and took another sip from his can, before hitting a few strokes on the
keyboard. The visualisation vanished, and another area appeared: the screen
went black, apart from lines of grey text near the bottom.</p>

<pre>
[Joined #physics-discuss]
&lt;Qubic&gt; the man himself. morning
&lt;foo&gt;   ye, what, i gotta be up at 6am
&lt;Qubic&gt; yeah, why are you still awake? what you been up to
&lt;foo&gt;   drink. now come on, why you want me here
&lt;Qubic&gt; i found someone working on producing tau neutrinos. interested?
</pre>

<p>That made Abdul sit up. His latest project needed a cheap and easy way to
produce neutrinos: sub-atomic particles that could pass through matter without
affecting it, only interacting one time in a billion. From the models Abdul
had been running on the computers, neutrinos would speed his process up by
many hundreds of time, and those specifically of the tau type were the best of
the lot. He was definitely interested.</p>

<pre>
&lt;foo&gt;   for sure. throw me an email addr, ill get in touch tomorrow
&lt;foo&gt;   but fer now, im going bed. gotta get _some_ sleep
</pre>

<p>Abdul's friend, who went by the name of Qubic, had helped a lot with this
particular project: he had set up the little cluster of computers sitting on
the desk, and written the software to get them talking and working on the
modelling system. Now, he'd tracked down someone whom Abdul would need if he
wanted to try the model in practice, someone who could provide these particles
to speed up the process. Abdul resolved to buy the man a drink sometime.</p>

<p>Not now, though. For the moment, he wanted sleep. He stood up, nearly
overbalancing but managing to correct himself. Stumbling over to the mattress
which lay on the floor across the room, he fell into it, sending a few stray
papers scattering across the floor and up a couple of feet into the air before
they swung back down.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Microwave</title>
 <link href="https://imrannazar.com/scifi/microwave" rel="alternate" type="text/html" title="Sci-fi Shorts: Microwave" />
 <id>https://imrannazar.com/scifi/microwave</id>
 <summary>Description of a system for generation and distribution of electrical power from orbiting nuclear power plants. Novel introduction.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:48:53 +0000</published>
 <content type="text/html"><![CDATA[
   <p>The problem had always been one of efficiency: getting electrical power into
the home while wasting as little of it as possible in the transfer. At the
far extreme of the home itself, the simplest way had always been to throw a
wire at the property, charged with an electrical current; no-one had really
found an easier way of getting electricity to the final usage points. There
were inevitable losses involved in transfer over wires, but that wasn't
where the major efficiency gains were to be made.</p>

<p>The way it had been before was this: a patchwork of locally-administered
generation plants, perhaps a few serving each city, mostly using methods
which hadn't changed for hundreds of years. By far the most common had been
the heating of water in order to spin magnets, which had compound problems:
use of a dirty fuel to heat the water, resulting in massive pollution, and
the inherent inefficiency of the process. People in the power business once
talked about 30% as if it was a good figure.</p>

<p>Of course, major problems arose if a city came close to running out of
power. Because each of these local generation plants was fixed, and it was
hugely expensive to build another one, the residents often faced such
concepts as the rolling blackout instead of having a reliable supply. Such
an idea sounded like a ridiculous way to run a city.</p>

<p>It took the invention of two seemingly seperate technologies to change the
status quo. The first was practicable nuclear fusion: the creation of a
little star in order to feed off its output. The Earth as a whole seemed to
get along just fine with fusion, lapping up the rays of the Sun; if the
planet could do it, the human race could adapt the technique.</p>

<p>The final race to build a viable fusion plant had been between China and
the United States, but the breakthrough came from neither quarter, but from
a research laboratory in France. The lab had been approached by both sides,
but refused to give the plant away in exclusivity; instead, the technology
was released for the world to use.</p>

<p>There was just one problem: size. The fusion plant was incredibly large,
and no city could viably set aside such a huge chunk of land to house what
was essentially a giant metal sphere. It took another invention before
that issue could be alleviated.</p>

<p>It was called the HCD by the research team who came up with it: the
High-power Collimating Diffractor. Its original target was satellite TV,
where large amounts of power were wasted by spreading a signal over spaces
which would never have a reception dish. Instead, the HCD split the signal
into focussed beams, which could then be directed every which way, towards
a specific dish on the ground or to another HCD for more refined splitting.</p>

<p>The real breakthrough hadn't come until Rihanna Johnson had her Eureka
moment: generating radio waves from a fusion plant, and splitting with a
HCD. The generation of radio from fusion was a simple enough matter, and
had been done before; the plant gave out incredibly intense light, which
could be shifted down to radio using technologies 50 years old. That wasn't
the main thrust of the idea, though; the word which made the world sit up
and take notice. That word was: space.</p>

<p>If fusion plants were so massively large that there was no way to house
them on land, they could be hoisted into space instead. From there, they
could generate high-powered microwaves, split into millions of fractions by
a network of HCDs in orbit around the Earth, which could then beam the
power down to reception dishes in every town and village.</p>

<p>It was a radical idea, not least because it meant abolishing the local
generation infrastructure that had been painstakingly put into place over
hundreds of years. The item which eventually forced the issue was, of
course, cost: the price of all fossil fuels was steadily rising, and at
some point in the late 21st century, all the accountants had worked out at
the same time that it would in fact be cheaper to set up the fusion network
than to keep the old plants running.</p>

<hr>

<p>That was the gist of the history lesson Ryan gave in his unofficial
capacity as tour guide for Fusion Pacific. He was a microwave researcher by
profession, but most people up here had to take multiple jobs, simply due
to a lack of personnel; it fell to him to show the tourists around.</p>

<p>Hawaii was the tethering point for Fusion Pacific: a huge cable, stronger
than diamond, attached the land mass of the Earth to the giant ball of the
power plant thousands of miles above. The space elevator had already been
in construction when the fusion network had been floated as an idea; since
the original plan had been to simply leave the end of the cable free in
space, the fusion plant was deemed to add only a small percentage to the
total mass of the system were it coupled to the endpoint.</p>

<p>There were two other stations in the fusion network: America, attached
somewhere in the Amazon, and Eurasia which was fixed to an island off the
coast of India. These had been the original three elevators, and three
fusion plants was more than enough for all the world's needs.</p>

<p>The tour normally consisted of a trip around the plant, starting at Earth
side and working around to star-side while Ryan explained the history of
the network. While working back to Earth-side, the tourists could examine
output graphs from the fusion plant if they so desired, or fiddle with a
sample light-frequency HCD that Ryan had put together. Instead of splitting
microwaves, it split red light into hundreds of thin beams, programatically
directed at will; it made for interesting lighting, if nothing else.</p>

 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: Sand</title>
 <link href="https://imrannazar.com/scifi/sand" rel="alternate" type="text/html" title="Sci-fi Shorts: Sand" />
 <id>https://imrannazar.com/scifi/sand</id>
 <summary>A man reflects on the detonation of a compressed antimatter bomb in his city. Short story.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:48:41 +0000</published>
 <content type="text/html"><![CDATA[
   <p>
The cold seeps through him as he sits on the sand, making a slow march from
his back down through his legs, and upwards towards his head. For the time
being at least, he is frontally protected from the insidious penetration of
the cold by a small fire, rapidly expending the little wood and few green
branches he had managed to gather.
</p><p>
Winter wasn't supposed to be this cold, he was sure.
</p><p>
As the flames struggle upward before him, fighting a stiff breeze which
threatens to drown everything in cold, he thinks about what happened to bring
his life to this point. Of course, the bomb had been the start of it; as it
had so abruptly ended so many lives, so it had ended any chance he had at
life. Little Steph, one of the things that had been right about this world,
his loving daughter: vaporised, along with the rest of Seattle, when the CAM
warhead had struck all that time ago.
</p><p>
His brain tells him it has been but three weeks since that day when the War
began, but every other part of him feels aged; he had lost any part of his
mind that felt anything, otherwise he knows that would feel the pain too. He
had been out of town that day, some kind of business at the Portland branch;
as he sat at his desk facing the window, a sudden blinding flash had him
covering his eyes for a moment. Every piece of electronic equipment in the
office had been rendered dead by the flash, and a few people knew what that
might mean.
</p><p>
Compressed anti-matter. Those bastards across the Atlantic had perfected their
new weapon, and felt that somewhere in the States was a good place to test it.
</p><p>
He knew immediately that he'd never be able to get back into the state, but he
tried anyway; his car wouldn't let him in (probably the electronics in there
had gone too), so he ended up jumping on a bus. He was promptly deposited,
about an hour later, at the state line, stopped by a police cordon. That
confirmed it; nothing else would have brought out such a response. It could
only be a CAM bomb.
</p><p>
So, that was it, then. The War with the Kingdom had started; the madman
Thompson had decided it was time to drop the bomb that would end the world.
The States would retaliate, of course; leaked documents had been splashed all
over the news a few months ago about a secret research project into some new
compressed form of anti-matter. "CAM", they called it, and everyone knew that
the President was just insane enough to use it in a pre-emptive strike on the
Kingdom. Looks like they had a project into this CAM stuff, as well.
</p><p>
And indeed, the bombs had flown across the Atlantic, vaporising Manchester and
Leeds; the reply had been to annihilate much of the eastern seaboard, and so
the two mad leaders successively ordered the destruction of each other's
demesnes. Eventually, probably because the CAM had run out, the missiles
stopped flying, and the smoking ruins of two countries were all that remained.
</p><p>
After about two weeks, he had finally been able to walk and hitch back to
where Seattle had been. Those documents had been right about the power of CAM;
nothing was left. Buildings, trees, people: in their place, nothing more than
sand. The shop where Steph had worked was gone, along with the block and the
streets around it; there wasn't even a strip of tarmac until a few miles out
of downtown.
</p><p>
He didn't know why he'd come back. Perhaps he had some small, insane hope of
seeing Steph again; deep in his mind, he knew that Steph was gone, but at that
time he'd never admit to that. He had scavenged the suburbs for a week, seeing
a few other people doing the same in that time, but he had spent most of that
time alone.
</p><p>
The fire had burned down while he was lost in thinking. Now, a small pile of
smouldering ashes sits in front of him; an occasional flicker of flame spurts
up when an unburned piece of wood gathers enough heat to ignite. It's time to
move on, find a warmer place to get some sleep, perhaps some food.
</p><p>
Sand. All that was left of his home.
</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Sci-fi Shorts: A Change of Clothing</title>
 <link href="https://imrannazar.com/scifi/change-of-clothing" rel="alternate" type="text/html" title="Sci-fi Shorts: A Change of Clothing" />
 <id>https://imrannazar.com/scifi/change-of-clothing</id>
 <summary>A chase and murder by a trained serial killer, as described from the killer&#039;s point of view. Short story.</summary>
 <category term="Original Writings" />
 <published>Fri, 22 Sep 2006 22:43:10 +0000</published>
 <content type="text/html"><![CDATA[
   <p>He never thought there would be so much blood.</p>

<p>Of course, he had been working towards this night. He had been through many
a simulation preparing, each one a virtual replica of the experiences and
emotions that would pass through his mind; each one rendered by a network
of computers, specifically ordered by the Organisation to reproduce the
feel of the moment down to the smallest detail.</p>

<p>Whenever he would step into the immersion tank to enter the simulation, and
don the mask which would feed his senses with virtual information, another
world would flood into his brain: sights, sounds, touches all provided by
the tank, on behalf of the simulation network. And it was a perfect world
in many ways.</p>

<p>The chase would always be reproduced perfectly. The pretty young thing he
would find in a deep level of a car park perhaps, or maybe in a back alley,
near-deserted in the small hours of the night. Her eyes would widen in
fear, the black pupils expanding as her flight response took hold, and then
she would run. And he would follow, purposefully and without excess haste,
for he always knew he would catch his prey before long.</p>

<p>The simulated victim would twist and turn through the streets of a deserted
city, seeking a way to escape her inevitably approaching predator, but
always he would be there: just behind, waiting for the slip to happen. And
it would happen. She would stumble and fall, maybe, or take a bad turning
and face a blank wall, and then the prey would be trapped; the implacable
hunter on one side, the immovable stone on the other.</p>

<p>Tonight, he had been judged by the lead committee of the Organisation to be
ready for a live chase. He had been transposed to a particularly run-down
inner suburb of the city, its glory days long since blown into the winds by
time and changing fashion. There he had seen his prey: a shapely young one,
perhaps nineteen, with auburn hair spilling down towards her waist. She
had sensed him somehow, turning back and showing those same wide eyes,
dark pupils bordered by hazel; and then she had run.</p>

<p>The chase had been especially satisfying, lasting just long enough for him
to be aroused, yet not dragging on until he would lose the urgent need to
catch his prey. It had also been convoluted, mapping out almost every alley
and street of that part of the city; he was sure that this one knew the
area well, and was confident of shaking him off. At least to begin with.</p>

<p>But he knew that the chase would end in his favour, and towards the end she
seemed to sense it too, her energy flagging, reserves failing as her body
finally gave in to the panic rushing through her. And as he grabbed her by
that length of auburn, a surge unlike any that had happened through the
simulations passed through him. He knew that this was real.</p>

<p>The Organisation had trained him not to be one of those animals dispensing
rape and murder on the world; the committee felt there were enough of those
rabid dogs without their contribution. Instead, he was one of the artists:
his speciality was the infliction of pain, delicate ribbons of flesh being
cut slowly from his prey with surgical precision, as she writhed beneath.</p>

<p>At first, he had been too quick to dispense the pain, his victim lapsing
into unconciousness almost immediately. But through the immersion tank, he
had learned where to provide pressure, when to cut, to keep her hovering
just concious, but still able to feel every ounce of the hurt he was
working to inflict. And now his initiation had come, his arts being worked
on a live subject for the first time, and he knew that this performance
would be judged favourably by the committee.</p>

<p>But incongrously, there was always one thing the simulations lacked, and
that was the flow of blood. The technicians said it was a simple problem of
physics; the processing power to calculate the flow of liquids on such a
precise scale simply wasn't there. How that could be, when the system gave
such accurate impressions of the fear in his prey's eyes, he'd never be
able to understand, but that was the simple fact of the matter.</p>

<p>And so it was that he was surprised by the sheer amount of blood released
by his art tonight. It covered him and the stone floor of the final alley
of the chase; it flowed freely from the limp body before him, which all the
time was discharging more out of itself. The very air was tinged with salt,
and he could taste metal in his breath if he opened his mouth. He was glad
he had taken notice of his trainer's final remark before this night.</p>

<p>Take a change of clothing.</p>

 ]]></content>
</entry>
<entry>
 <title type="html">Collapsible Nested Lists in Vanilla JavaScript</title>
 <link href="https://imrannazar.com/articles/vanilla-js-trees" rel="alternate" type="text/html" title="Collapsible Nested Lists in Vanilla JavaScript" />
 <id>https://imrannazar.com/articles/vanilla-js-trees</id>
 <summary>Details regarding the implementation of a collapsible tree-style nested list using standards-compliant HTML and CSS, utilising JavaScript and the Document Object Model.</summary>
 <category term="Articles" />
 <published>Fri, 22 Sep 2006 21:40:53 +0000</published>
 <content type="text/html"><![CDATA[
   <style>
#domtree, #domtree ul, #domtree ul ul {
  list-style: none outside;
  margin-left: 16px;
}

#domtree li.treehide ul,
#domtree li li.treehide ul {
  display: none;
}

#domtree li.treeshow ul,
#domtree li li.treeshow ul {
  display: block;
}

#domtree li.treehide .clk,
#domtree li li.treehide .clk {
  text-decoration: underline;
  cursor: pointer;
  padding-left: 16px;
  background: url('/content/img/css-trees-plus.gif') no-repeat center left;
}

#domtree li.treeshow .clk,
#domtree li li.treeshow .clk {
  text-decoration: underline;
  cursor: pointer;
  padding-left: 16px;
  background: url('/content/img/css-trees-minus.gif') no-repeat center left;
}
</style>
  <script type='text/javascript'><!--
function toggle(x){
  x.className = (x.className == 'treeshow') ? 'treehide' : 'treeshow';
}
//-->
  </script>
  <p>We all know that a tree, like the one seen in Windows' File Explorer,
  is nothing more than a nested list. But is it possible to code a tree up
  in HTML/CSS as a nested list?</p>
  <p>Let's start off with the list. This is a snippet of a standard file
  tree, organised in "folders".</p>
  <samp>
  <pre>
&lt;ul&gt;
 &lt;li&gt;
  Graphics
  &lt;ul&gt;
   &lt;li&gt;&lt;a href='gpu.h'&gt;gpu.h: Function prototypes&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href='gpu.c'&gt;gpu.c: Graphic output implementation&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;
    Debug Output
    &lt;ul&gt;
     &lt;li&gt;&lt;a href='dbgout.h'&gt;dbgout.h: Output prototypes&lt;/a&gt;&lt;/li&gt;
     &lt;li&gt;&lt;a href='dbgout.c'&gt;dbgout.c: Output fixed-width font drawing&lt;/a&gt;&lt;/li&gt;
     &lt;li&gt;&lt;a href='font5x7.h'&gt;font5x7.h: Fixed-width font definitions&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
   &lt;/li&gt;
  &lt;/ul&gt;
 &lt;/li&gt;
&lt;/ul&gt;</pre></samp>
  <p>And this is what we get from that code.</p>
  <ul>
   <li>
    Graphics
    <ul>
     <li><a href='gpu.h'>gpu.h: Function prototypes</a></li>
     <li><a href='gpu.c'>gpu.c: Graphic output implementation</a></li>
     <li>
      Debug Output
      <ul>
       <li><a href='dbgout.h'>dbgout.h: Output prototypes</a></li>
       <li><a href='dbgout.c'>dbgout.c: Output fixed-width font drawing</a></li>
       <li><a href='font5x7.h'>font5x7.h: Fixed-width font definitions</a></li>
      </ul>
     </li>
    </ul>
   </li>
  </ul>
  <p>Having a tree means that each branching node can expand or collapse, to
  show or hide the elements of the tree within it. The showing and the hiding
  isn't so difficult; the <code>display</code> property in CSS allows us to
  do this pretty quickly, if we define two classes:</p>
  <samp><pre>
ul.hide { display: none; }
ul.show { display: block; }</pre></samp>
  <p>Of course, it's not quite that simple. You can't change the state of a
  <code>UL</code> very easily (clicking on it won't do); but you can
  change the state of an <code>LI</code>. So we move the two classes to the
  enclosing LI:</p>
  <samp><pre>
li.hide ul { display: none; }
li.show ul { display: block; }</pre></samp>
  <p>So, we have the CSS for hiding the tree. But how do we switch states?
  How can we show and hide the nodes at will? That's where the DOM comes in.
  If we put the description of the tree item ("Debug Output" for example")
  in an active element (<code>DIV</code> or <code>A</code> maybe), we can
  attach DOM events to it.</p>
  <p>I've decided not to use <code>A</code>, because an anchor requires a
  <code>href</code>, and using a link of <code>#</code> will clutter up
  your browser's History facility. So, let's use a <code>DIV</code>.</p>
  <p>What do we want to happen when we click the <code>DIV</code>? Basically,
  just flip the state of the parent <code>LI</code>, such that the
  <code>UL</code>s underneath are visible.</p>
  <samp><pre>
&lt;ul&gt;
 &lt;li class='hide'&gt;
  &lt;div onclick='toggle(this.parentNode)'&gt;Graphics&lt;/div&gt;
  &lt;ul&gt;
   &lt;li&gt;&lt;a href='gpu.h'&gt;gpu.h: Function prototypes&lt;/a&gt;&lt;/li&gt;
   &lt;li&gt;&lt;a href='gpu.c'&gt;gpu.c: Graphic output implementation&lt;/a&gt;&lt;/li&gt;
   &lt;li class='hide'&gt;
    &lt;div onclick='toggle(this.parentNode)'&gt;Debug Output&lt;/div&gt;
    &lt;ul&gt;
     &lt;li&gt;&lt;a href='dbgout.h'&gt;dbgout.h: Output prototypes&lt;/a&gt;&lt;/li&gt;
     &lt;li&gt;&lt;a href='dbgout.c'&gt;dbgout.c: Output fixed-width font drawing&lt;/a&gt;&lt;/li&gt;
     &lt;li&gt;&lt;a href='font5x7.h'&gt;font5x7.h: Fixed-width font definitions&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
   &lt;/li&gt;
  &lt;/ul&gt;
 &lt;/li&gt;
&lt;/ul&gt;</pre></samp>
  <p>So when you click the "Graphics" <code>DIV</code>, <code>toggle()</code>
  runs and flips the top <code>LI</code> from <code>hide</code> to <code>show</code>.
  And of course, if you click it again, it flips back to <code>hide</code>.
  We'll need some JavaScript to do this; fortunately, JS gives us the ternary
  operator, where we can select two options based on a condition.</p>
  <samp><pre>
function toggle(x)
{
  x.className = (x.className=='show') ? 'hide' : 'show';
}</pre></samp>
  <p>What this means is: "If the className is <code>show</code>, set it to
  <code>hide</code>, otherwise [ie. if it's not <code>show</code>] set it to
  <code>show</code>". Since there're only two possibilities for the class
  name, you can see that this toggles between the two.</p>
  <p>Just before we get to an actual working example, you should remember that
  you'll have to define CSS for each level of menu that we go down, since
  the properties won't inherit between <code>UL</code>s if there's an
  <code>LI</code> in the way (which there always is).</p>
  <p>So now, we can put it all together, and come up with a simple tree that
  is collapsible/expandable with a bit of DOM fiddling.</p>
  <samp>
  <ul id='domtree'>
   <li class='treehide'>
    <div class='clk' onclick='toggle(this.parentNode)'>Graphics</div>
    <ul>
     <li><a href='gpu.h'>gpu.h: Function prototypes</a></li>
     <li><a href='gpu.c'>gpu.c: Graphic output implementation</a></li>
     <li class='treehide'>
      <div class='clk' onclick='toggle(this.parentNode)'>Debug Output</div>
      <ul>
       <li><a href='dbgout.h'>dbgout.h: Output prototypes</a></li>
       <li><a href='dbgout.c'>dbgout.c: Output fixed-width font drawing</a></li>
       <li><a href='font5x7.h'>font5x7.h: Fixed-width font definitions</a></li>
      </ul>
     </li>
    </ul>
   </li>
  </ul>
  </samp>
  <p>Here, I've just added some styling to the text <code>DIV</code>, which can change
  along with the parent <code>LI</code> state just as the <code>UL</code>
  does. Again, the inheritance of properties will be lost between levels,
  so just put in an extra line for each level down.</p>
  <p>Now we have just one problem. As you can see, the page loads with
  the Graphics item collapsed. What if you don't have JS running? Click on
  the <code>DIV</code> and nothing happens; you can't get to the list
  underneath! Obviously a problem. The way to alleviate this is to have
  everything expanded by default instead of collapsed; if you need to,
  use an <code>onload</code> tree collapse so that the tree will collapse
  if you run JS, and stay expanded if you don't.</p>
  <samp><pre>
function treeCollapse(){
  var list = document.getElementById('yourtree').getElementsByTagName('li');
  for(var i=0;i&lt;list.length;i++) list[i].className = 'hide';
}</pre></samp>
  <p>This'll just get a list of all the <code>LI</code>s in the tree, and
  set them to class <code>hide</code>.</p>
  <p>So, that's how to make a nested list into an expandable tree.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">An Introduction to Bitwise Operators</title>
 <link href="https://imrannazar.com/articles/bitwise-operators" rel="alternate" type="text/html" title="An Introduction to Bitwise Operators" />
 <id>https://imrannazar.com/articles/bitwise-operators</id>
 <summary>For almost as long as the computer has existed, programmers and developers have had to deal with the computer&#039;s representation of numbers, the binary numbering system. The unique properties of binary allow the application of Boolean mathematics to common manipulations. This article provides a run-down of the common Boolean operations, including their syntax in C-derived programming languages, and provides examples of where such operations might be used in everyday development.</summary>
 <category term="Articles" />
 <published>Fri, 22 Sep 2006 21:39:57 +0000</published>
 <content type="text/html"><![CDATA[
     <p>Computers work with binary numbers. The binary system allows for some cool
  manipulations to be performed on the per-digit level; the problem is that
  relatively few people learn about these operations, since they seem at first
  glance to be quite complicated. This document will show that they're not,
  really.</p>
  <p>For this quick run-through, I'll be assuming you know what the binary
  numbering system is, and how it works; furthermore, I'll assume a little
  familiarity with working in binary.

  Everyone who uses a computer, whether it be to connect to the
  Internet, for video games, or
  simply to edit a Word document, will have experienced the binary numbering
  system, as this is how all computers function internally. However, to make
  binary manipulations, you will need a slightly more advanced idea of how
  this system operates.
  
  I'll also be presenting any code
  examples using the syntax of C and its syntactical derivatives (C++, PHP,
  Java and the like). Don't worry if you don't know the C syntax for the
  operators; I'll be putting a small table at the end of the document.</p>
  <h2 id='and'>AND: Putting on the mask</h2>
  <p>The first operation to look at is called AND. It's called that because
  that's exactly what it does: take two inputs, and only return any output
  if both input 1 AND input 2 are on.</p>
  <table>
   <thead><tr><th>in1</th><th>in2</th><th>in1 AND in2</th></tr></thead>
   <tbody>
    <tr><td>0</td><td>0</td><td>0</td></tr>
    <tr><td>0</td><td>1</td><td>0</td></tr>
    <tr><td>1</td><td>0</td><td>0</td></tr>
    <tr><td>1</td><td>1</td><td>1</td></tr>
   </tbody>
  </table>
  <p>That table is an example of a <em>truth table</em>; it plots out all
  the possible combinations of inputs, and what the operator will do with
  them. As you can see, the AND operator only returns 1 if both inputs
  are 1. But how does that help us in the real world, of numbers bigger
  than one bit?</p>
  <h2>Using AND to mask values</h2>
  <p>The major thing that can be done with AND is <em>masking</em>: only
  using the part of a number that you want to use. For example, let's say
  you have a 32-bit variable, and you're incrementing it in a loop. But you
  want to wrap the value after 255, back to 0. A simple case of using an
  <code>if</code> statement, you may think. But think again.</p>
  <samp> 
   <h3>AND: Masking a 32-bit value</h3>
   <pre class="inner">while(1)
{
    i++;
    <s>// How we'd do this with an if clause
    // if(i &gt; 255) i = 0;</s>

    <s>// How to do it with AND</s>
    i = i &amp; 255;
}</pre>
  </samp>
  <p>What's happening here? Let's have a look at a normal case first; say
  <code>i</code> is at a value of 77. The AND operation looks like this:</p>
  <samp>
   <h3>AND: Masking at i=72</h3>
   <pre class="inner">00000000 00000000 00000000 01001101
00000000 00000000 00000000 11111111   [AND]
-----------------------------------
00000000 00000000 00000000 <s>01001101</s></pre>
  </samp>
  <p>The AND "mask" is essentially passing through the low 8 bits of
  <code>i</code> into the result. In this case, 77 fits fine into 8
  bits, so no change. What happens at the borderline case: when 255
  becomes 256?</p>
  <samp>
   <h3>AND: Masking at i=256</h3>
   <pre class="inner">00000000 00000000 00000001 00000000
00000000 00000000 00000000 11111111   [AND]
-----------------------------------
00000000 00000000 00000000 <s>00000000</s></pre>
  </samp>
  <p>As stated above, the low 8 bits of <code>i</code> are being passed
  through. That's 0. The rest of the value, including the '256' bit, is
  essentially ignored by the mask, meaning the value automagically wraps
  from 255 to 0. Quite useful, you'll admit.</p>
  <h2>AND's role in IP addressing</h2>
  <p>Something else you can do with AND is to clear a certain portion of a
  value. For example, you want to check the network that an IP address
  lives on. An IP address is just another 32-bit number, and the subnet
  mask that accompanies it is exactly that: a mask, that's applied to the
  IP using the AND operator, to find the subnet for that IP address.</p>
  <p>Let's take my setup at home. I have a few computers at home, and
  they all have addresses in a private IP range. One of those computers is
  <code>172.16.55.37</code>, with a subnet mask of <code>255.255.255.224</code>;
  how does the router know which network I'm coming from?</p>
  <samp>
   <h3>AND: What subnet are you on?</h3>
   <pre class="inner">IP address: 10101100.00010000.00110111.00100101
Snet Mask:  11111111.11111111.11111111.11100000
AND:        -----------------------------------
Subnet:     <s>10101100.00010000.00110111.001</s>00000  [172.16.55.32]</pre>
  </samp>
  <p>So when the router sees a packet destined for </code>172.16.55.37</code>,
  it applies this AND operation, works out that the network is in its
  route table, and forwards the packet. In other words, the Internet
  wouldn't work without the AND operator.</p>
  <h2>AND used to clear a bit</h2>
  <p>A final example for AND: When you want to make a Windows application,
  you generally want to display a window, and windows can have various
  styles associated with them. The most commonly used style is
  <code>WS_OVERLAPPEDWINDOW</code>, which is just a number given an
  easier-to-read name: it combines various styles which tell Windows to
  provide a caption, system menu, minimise and maximise buttons.</p>
  <p>But what if you don't want a minimise button? You can build the
  style you need by taking the normal one, and cutting out the value for
  <code>WS_MINIMIZEBOX</code>. The style values were set with just this
  idea in mind: simple styles are binary power values, and complicated
  styles combine them together.</p>
  <p>So let's give that a go: a window with no minimise button.</p>
  <samp>
   <h3>AND: Clearing a bit</h3>
   <pre class="inner">OVERLAPPEDWINDOW:  00000000 11001111 00000000 00000000
MINIMIZEBOX:      (00000000 00000010 00000000 00000000)
Clear mask:        11111111 11111101 11111111 11111111
AND:               -----------------------------------
Overall style:     00000000 110011<strong>0</strong>1 00000000 00000000</pre>
  </samp>
  <p>If the new value is passed to Windows, you'll get a shiny new window
  with no minimise button. To generate the clear mask, you can use the
  NOT operator, which we'll be coming to later.</p>
  <h2 id='or'>OR: Setting bits</h2>
  <p>The second operator we'll look into is called OR. And as you can guess,
  it's called OR for a reason: it takes two inputs, and gives an output if
  either one or the other, or both, is set. Here's another of those truth tables.</p>
  <table>
   <thead><tr><th>in1</th><th>in2</th><th>in1 OR in2</th></tr></thead>
   <tbody>
    <tr><td>0</td><td>0</td><td>0</td></tr>
    <tr><td>0</td><td>1</td><td>1</td></tr>
    <tr><td>1</td><td>0</td><td>1</td></tr>
    <tr><td>1</td><td>1</td><td>1</td></tr>
   </tbody>
  </table>
  <p>Note how it doesn't matter whether <code>in1</code> is on or off; if
  <code>in2</code> is on, the result is on. And, of course, the inverse
  applies. So, how can that be used in the real world?</p>
  <p>The major application of OR is in setting bits; filling a portion of
  a value with 1's. Let's take the Windows styles from above: you may want
  not just a normal window, but a window which can handle vertical scrolling
  of its contents. Luckily, it's simple to define such a window: just tack
  the <code>WS_OVERLAPPEDWINDOW</code> default style and
  <code>WS_VSCROLL</code> together, thus.</p>
  <samp>
   <h3>OR: Filling in a value</h3>
   <pre class="inner">
OVERLAPPEDWINDOW:  00000000 11001111 00000000 00000000
VSCROLL:           00000000 00100000 00000000 00000000
OR together:       -----------------------------------
New window style:  00000000 11<strong>1</strong>01111 00000000 00000000</pre>
  </samp>
  <p>By using AND and OR in this manner, it's quite easy to build up
  exactly the style of window you're looking for.</p>
  <h2 id='xor'>XOR: OR with a twist</h2>
  <p>OR is the operation that allows you to set a bit if either or both of
  two inputs is set. But what if you only want to check either, and not
  both? There is an operator for that, and it's called the Exclusive OR,
  XOR for short. Another truth table for you:</p>
  <table>
   <thead><tr><th>in1</th><th>in2</th><th>in1 XOR in2</th></tr></thead>
   <tbody>
    <tr><td>0</td><td>0</td><td>0</td></tr>
    <tr><td>0</td><td>1</td><td>1</td></tr>
    <tr><td>1</td><td>0</td><td>1</td></tr>
    <tr><td>1</td><td>1</td><td>0</td></tr>
   </tbody>
  </table>
  <p>Now, it might seem a bit esoteric and theoretical, to have an operator
  that only sets output if either input is set, and not both. However, the
  XOR operation does come in useful.</p>
  <h2>XOR to clear a value</h2>
  <p>If you have a variable or a CPU register, and you want to clear it to 0,
  you don't care about what's inside; those contents will be obliterated
  anyway. Of course, you can simply move "0" into that variable, but in some
  cases that might be a problem. Instead, you can use XOR.</p>
  <samp>
   <h3>XOR: Clearing to zero</h3>
   <pre class="inner">Random value: 11001001 01001110 11010010 11110001
Value again:  11001001 01001110 11010010 11110001
XOR:          -----------------------------------
Output:       00000000 00000000 00000000 00000000</pre>
  </samp>
  <p>For every one of the 32 bits in that example, either the top or the
  bottom line of the truth table matched, which means the output was 0 in
  both cases. The end result is, of course, that all the bits of the value
  turn out as 0 after the XOR operation. Now, why would one want to perform
  such an operation? Take a look at this example, in Intel assembly.</p>
  <samp>
   <h3>XOR: Assembly usage</h3>
   <pre class="inner">mov eax, 0       ; Assembles to 5 bytes
xor eax, eax     ; Assembles to 1 byte</pre>
  </samp>
  <p>If you're at a premium for space, it's obvious which of the two you'd
  pick; instead of wasting 4 bytes of space, a bitwise operator can do the
  same job.</p>
  <h2>XOR to flip a bit</h2>
  <p>The other major application of XOR is to flip a bit, or range of bits,
  within a value. If you take a look at the truth table in two halves, the
  top half is essentially the bottom half upside-down; and that flipping
  is controlled by the value of <code>in1</code>. This comes in very useful
  for certain situations.</p>
  <p>For example, let's say you've been tasked with producing a square wave:
  a constant series of pulses, 64 then 191, then 64, then 191. You could
  implement a complicated series of <code>if</code> statements, or you
  could use a simple XOR.</p>
  <samp>
   <h3>XOR: Making a 1kHz square wave</h3>
   <pre class="inner">char output = 64;
while(1)
{
    output = output ^ 255;
    usleep(500);    <s>// sleep for half the wave period</s>
}</pre>
  </samp>
  <p>So, what's happening here? The output value starts at 64, and gets changed
  by the XOR every time the loop runs. How does that change manifest itself?</p>
  <samp>
   <h3>XOR: Sending the square wave high</h3>
   <pre class="inner">output: 01000000
Mask:   11111111
XOR:    --------
Result: 10111111</pre>
  </samp>
  <p>So we started at 64, and the XOR has flipped all the bits, to 191. After
  500 milliseconds, the loop is re-entered, and the XOR gets applied again:</p>
  <samp>
   <h3>XOR: Sending the same wave low</h3>
   <pre class="inner">output: 10111111
Mask:   11111111
XOR:    --------
Result: 01000000</pre>
  </samp>
  <p>And as if by magic, the XOR returns the result we entered with the first
  time: 191 gets flipped to 64. Because the value is 64 for 500 microseconds,
  and 191 for another 500 microseconds, the overall wave period is 1 millisecond,
  and we've produced the 1kHz square wave, with just one XOR operation.</p>
  <h2 id='not'>NOT: The unary one</h2>
  <p>If all you want to do is flip the whole of a value, as in the above
  example, there is an alternative. It's called NOT, and it's different to the
  rest of the bitwise operators we've covered so far. Instead of taking two
  inputs, it just takes one; the output is the opposite of the input.</p>
  <table>
   <thead><tr><th>x</th><th>NOT x</th></tr></thead>
   <tbody>
    <tr><td>0</td><td>1</td></tr>
    <tr><td>1</td><td>0</td></tr>
   </tbody>
  </table>
  <p>NOT is one of those more esoteric operations; it doesn't see much use.
  One place where it can be used to good effect is to generate masks for use
  in the AND operation. Let's say you want to mask off all the bits of a
  value except the bottom two. Instead of hassling around with long strings
  of binary or hexadecimal digits, we can let bitwise operators do the grunt
  work for us.</p>
  <samp>
   <h3>NOT: Generating an AND mask</h3>
   <pre class="inner">value = value &amp; (~3);</pre>
  </samp>
  <p>Alright; short, succinct, but what's it doing? Let's take a look at
  the binary level.</p>
  <samp>
   <h3>NOT: How the generation happens</h3>
   <pre class="inner">Three:  00000000 00000000 00000000 00000011
NOT 3:  11111111 11111111 11111111 11111100
Value:  11001001 00011110 10001101 00111011
AND:    -----------------------------------
Result: <s>11001001 00011110 10001101 001110</s>00</pre>
  </samp>
  <p>In this way, you can easily generate the masks you need for your AND
  operations, without having to dig deep into hexadecimal strings and
  remembering any combination tables; NOT's doing the hard work for you.</p>
  <h2 id='shift'>Shifts: Do the shuffle</h2>
  <p>So far, the bitwise operators have been 1-bit affairs: take one bit
  from an input (or two), give one bit of output. There are operators,
  however, that take a whole string of binary digits, and do simple operations
  with that. The major example of those operators is the shift.</p>
  <p>Shifting comes in two variants: left and right. As you can probably
  guess, a left shift takes a binary string of values and shifts it left, 
  pushing it up the binary powers. Let's take a look with an example.</p>
  <samp>
   <h3>Left shift: Pushing a value up</h3>
   <pre class="inner">Before: 0000<s>1111</s>
Left 1: 000<s>1111</s>0
Left 2: 00<s>1111</s>00
Left 3: 0<s>1111</s>000</pre>
  </samp>
  <p>The 1's get pushed up from the bottom of the value, towards the top;
  the gaps that are left are filled in by 0's. If you look carefully, you'll
  note that this is essentially equivalent to multiplying the value by powers
  of two: before shifting, we had 15. Shift left by 1 and we end up with 30;
  left by 2 gives us 60, and left by 3 gives 120.</p>
  <p>However, what happens if we start with a 1 near the top, and then start
  shifting left? Let's take a look.</p>
  <samp>
   <h3>Left shift: The bit bucket</h3>
   <pre class="inner">Before: 0<s>1100101</s>
Left 1: <s>1100101</s>0
Left 2: <s>100101</s>00
Left 3: <s>00101</s>000</pre>
  </samp>
  <p>The value got shifted along sure enough, and 0's were inserted at the
  bottom, but where did the upper 1's go? The answer is, they vanished;
  basically, they fell off the end of the value as a result of the shifting
  operation. If you decide to use shifts, keep in mind that this will happen
  if you run out of space for the bits.</p>
  <p>Also note how the most-significant bit changes during the successive
  shift operations. If you're dealing with signed values, the most significant
  bit is often used to denote the sign (1 meaning that this is a negative
  number); in this case, your number is going from positive to negative, then
  back to positive! That is one disadvantage of the shift operation that has
  to be kept in mind when you use it.</p>
  <p>The right shift is very similar to the left shift, only it acts in the
  reverse direction: bits get moved to the right, and 0's are inserted from
  the left hand side.</p>
  <samp>
   <h3>Right shift: Pushing down</h3>
   <pre class="inner">Before:  00<s>111</s>000
Right 1: 000<s>111</s>00
Right 2: 0000<s>111</s>0
Right 3: 00000<s>111</s></pre>
  </samp>
  <p>Just as left shift can be thought of as multiplication by a binary
  power, right shift can be used to divide by a binary power; in the case
  above, 56 becomes 28, then 14, then 7, simply by successive shifts to
  the right.</p>
  <p>Just as with the left shift also, the right shift provides no safeguards
  if 1's are at the low end of the scale. In the example above, another right
  shift would yield a value of 3, since the lowest 1 simply drops off the end
  of the value.</p>
  <p>Also just like the left shift, there's no safeguard on the highest bit;
  if it started out as 1 (which in a signed value denotes negative), a right
  shift would fill in 0's, making the value positive. For that reason, processors
  and programming languages often offer an "arithmetic" right shift operation,
  which fills with 0 if the top bit was 0, and fills with 1 if the top bit was
  1; by using the arithmetic right shift, the sign of the value is preserved.</p>
  <p>That's all well and good, throwing values around inside a binary string.
  But to what end can it be put? How can shifts be used in the real world?</p>
  <h2>Shifts to combine values</h2>
  <p>Let's say you have in your possession four 8-bit values, and you wish to
  build a 32-bit value by tacking them all together. The left shift makes this
  a very easy task to accomplish.</p>
  <samp>
   <h3>Left shift: Building a value</h3>
   <pre class="inner">Values: 11001010, 00111010, 01001101, 00110011
Pushing all values into 32-bit variables:

var4:  00000000 00000000 00000000 <s>00110011</s>
var3:  00000000 00000000 <s>01001101</s> 00000000  &lt;-- left shift 8
var2:  00000000 <s>00111010</s> 00000000 00000000  &lt;-- left shift 16
var1:  <s>11001010</s> 00000000 00000000 00000000  &lt;-- left shift 24
OR:    -----------------------------------
Final: 11001010 00111010 01001101 00110011

value = var4 | (var3 &lt;&lt; 8) | (var2 &lt;&lt; 16) | (var1 &lt;&lt; 24);</pre>
  </samp>
  <p>Similarly, if you wanted to split that 32-bit value up into 8-bit
  chunks, you could simply perform a successive right-shift by 8, in
  conjunction with an AND operation to mask off the part of the result
  you're looking for.</p>
  <samp>
   <h3>Right shift: Splitting a value</h3>
   <pre class="inner">
Initial: 11001010 00111010 01001101 00110011
Mask:    00000000 00000000 00000000 11111111
AND:     -----------------------------------
var4:                               00110011

RShift:  00000000 11001010 00111010 01001101
Mask:    00000000 00000000 00000000 11111111
AND:     -----------------------------------
var3:                               01001101

RShift:  00000000 00000000 11001010 00111010
Mask:    00000000 00000000 00000000 11111111
AND:     -----------------------------------
var2:                               00111010

RShift:  00000000 00000000 00000000 11001010
Mask:    00000000 00000000 00000000 11111111
AND:     -----------------------------------
var1:                               11001010

var4 = value &amp; 255;
var3 = (value &gt;&gt; 8) &amp; 255;
var2 = (value &gt;&gt; 16) &amp; 255;
var1 = (value &gt;&gt; 24) &amp; 255;</pre>
  </samp>
  <p>A little bit long-winded, at least when written down in raw binary. Keep
  in mind, though, that the computer can do this at a stupidly high pace,
  especially when you use operators designed to work with bits.</p>
  <h2>Shifts used to multiply</h2>
  <p>Another use of shifts is to multiply values by multiplers that aren't
  direct binary powers. This isn't such a common operation any more, since
  multiplier units are quite quick nowadays, but if you ever come across a
  weird sequence of shift operations in some old code, you'll know what it's
  doing, and why it's there.</p>
  <p>In the old VGA days, the most common graphic mode used on PCs had 320
  pixels to a line. Pixels were written to the screen in a flat framebuffer:
  a portion of memory which translated directly to the screen, 320 bytes to
  a line. That meant finding out a location in memory, given an X and Y
  coordinate to draw to. The formula is pretty simple, but the multiplier
  units of the CPUs back then were quite slow, so every advantage was sought
  out.</p>
  <samp>
   <h3>Left shift: Multiplying by 320</h3>
   <pre class="inner">Memory Location = (y * 320) + x
                = (y * 256) + (y * 64) + x
		= (y &lt;&lt; 8) + (y &lt;&lt; 6) + x</pre>
  </samp>
  <p>Since shifts were orders of magnitude faster than multiplies, this
  series of two shifts and two adds was done much more quickly than one multiply
  and one add. Of course, you probably won't see this so much any more, since
  CPUs actually got good at multiplying, but it's possible you'll come across
  this kind of technique in another place.</p>
  <h2>The End</h2>
  <p>So, that's all the bitwise operators you'll come across in your travels
  through programming. Some of them may come in very useful, and some may be
  used less often, but have no doubt: they'll all be used sometime.</p>
  <p>A final note: This table shows how C-syntax languages denote the bitwise
  operators.</p>
  <table>
   <thead><tr><th>Operator</th><th>Symbol</th><th>Syntax</th></tr></thead>
   <tbody>
    <tr><td>AND</td><td>Ampersand</td><td>x &amp; y</td></tr>
    <tr><td>OR</td><td>Vertical pipe</td><td>x | y</td></tr>
    <tr><td>XOR</td><td>Caret</td><td>x ^ y</td></tr>
    <tr><td>NOT</td><td>Tilde</td><td>~ x</td></tr>
    <tr><td>Left shift</td><td>Two less-than signs</td><td>x &lt;&lt; y</td></tr>
    <tr><td>Right shift</td><td>Two greater-than signs</td><td>x &gt;&gt; y</td></tr>
   </tbody>
  </table>
  <p>Placed into the public domain by Imran Nazar, 2006.</p>
 ]]></content>
</entry>
<entry>
 <title type="html">Virus Detection with Message Digests</title>
 <link href="https://imrannazar.com/hacks/virus-detection-with-md5" rel="alternate" type="text/html" title="Virus Detection with Message Digests" />
 <id>https://imrannazar.com/hacks/virus-detection-with-md5</id>
 <summary>One day in 2006, I was set a short challenge: write an article of around 500 words on the topic of MD5 digests. This article was the result: an explanation of what it means when a computer generates a digest of a message, and a look at where message digests can be used. In particular, focus is given to automatic generation of digests for executable files, and how this can be used to detect possible manipulations of the files by viruses.</summary>
 <category term="Quick Hacks" />
 <published>Fri, 22 Sep 2006 21:38:53 +0000</published>
 <content type="text/html"><![CDATA[
   <p>Files stored in a computer are simply streams of numbers. A text file, for
instance, has a number for each letter or number in the text; a graphic file
has a number for each element of colour. Computer programs are also files:
each number tells the computer to perform a function like adding two numbers
together, or storing a number in another file.</p>
<p>The problem is that, because programs are just files like any other files,
they can be changed: certain numbers modified, or new streams added in the
middle of the file. This is one way in which viruses are able to infect a
file; they may add to a program file, and the next time that program is run,
the virus is executed and performs the functions it was designed to do.</p>
<p>
One of the best ways to alleviate this is to use a technique known as the
'message digest': a number which describes the entire contents of a file. A
simple example would be an algorithm like the following:</p>
<p>If each letter of the alphabet is assigned a number, A being 1, B being 2 and
so forth, it's possible to add all the letters in a text file together, to
obtain a "check-sum"; a sum of the contents of the file, which can be used to
check it. As an example, <code>HELLO WORLD</code> would add up to 127.</p>
<p>One of the problems with this simplest example of message digest algorithm is
that the space could be removed entirely, and the checksum would be the same;
also, the message could be changed and more content added, as long as the
total of all the letters was still 127. As a result, more complex algorithms
have been developed to take these issues into account.</p>
<p>When these methods are used on a program file, they generate a number which is
unique to the combination of numbers within that file. If anything changes,
like an instruction being changed or instructions being added by a virus, the
digest number will change.</p>
<p>This can be used to detect viruses every time a program is run. The process is
relatively simple: when the program is first installed, a digest is generated
based on that program file. Every time the program is used, the digest is
again calculated, and if the numbers differ, some outside agent has changed
the file.</p>
<p>One of the most popular implementations of this system is used inside Windows,
known as File Protection; it's used on files which are important to the
system, such as device drivers. If Windows detects that one of the files has a
different digest to that which it knows about, the user will be alerted to the
fact that a system file has been changed. Many other systems are also in place
in other software packages to perform similar functions.</p>

 ]]></content>
</entry>
<entry>
 <title type="html">The Smallest Nintendo DS ROM</title>
 <link href="https://imrannazar.com/hacks/the-smallest-nds-rom" rel="alternate" type="text/html" title="The Smallest Nintendo DS ROM" />
 <id>https://imrannazar.com/hacks/the-smallest-nds-rom</id>
 <summary>Embedded development is often focused on the size of the resultant binary, especially on platforms where this factor is important. On the Nintendo GBA and DS, the homebrew toolchain is able to generate well-optimised binaries, but programs with equivalent functionality tend to have very different sizes. This article looks into why that is the case, and explores the format of a Nintendo DS binary file in an attempt to make the smallest DS binary possible.</summary>
 <category term="Articles" />
 <published>Fri, 22 Sep 2006 21:37:38 +0000</published>
 <content type="text/html"><![CDATA[
     <p>Have you ever wondered what exactly is inside a Nintendo DS ROM file, 
  and why the simple DS demos are so much larger than their GBA equivalents?
  Some people have, and this page documents their exploits.</p>
  <h2>Introduction</h2>
  <p>It started innocently enough. I was looking for a small ROM which
  would be used to test the framebuffer display mode of DSemu, a Nintendo DS
  emulator. LiraNuna agreed to put a small C demo together, to fill the 'main'
  screen with red, demonstrating the framebuffer's use. When compiled and
  spliced up, the .nds ended up at around 7.5KB.</p>
  <p>That, LiraNuna thought, was a bit large for something that did so little
  as his demo evidently did. Stepping through with DSemu's debugger, I
  noticed a whole lot of code being run which wasn't strictly required:
  setting up cache parameters and the stack, clearing out regions of memory,
  and such like. Referred to as the crt0, this code is inserted into every
  project, to safeguard the execution environment.</p>
  <p>Furthermore, there was the standard ARM7 code also inserted into the
  .nds file, which does such things as set up the touchscreen. All this, we
  thought, was a bit over-the-top for a demo that was literally doing almost
  nothing. So, the cut-down began.</p>
  <h2>Early stages: Chopping the ARM7</h2>
  <p>First off, LiraNuna thought the functionality of the ARM7 wasn't
  particularly required for this demo. So, the thought process went, why not
  simply tell that 'sub' CPU to enter an infinite loop and not do anything?
  The reasoning was sound, and so the ARM7 source file was replaced with a
  simple assembly file, looking something like this.</p>
  <samp> 
   <h3>ARM7 cut-down: Infinite loop</h3>
   <pre>main: b main</pre>
  </samp>
  <p>Once put together, that reduced the size of the overall .nds file
  by quite a way; down to approximately 5KB. However, I still thought that
  was a touch large. A quick peek into the .nds file showed why that was:
  the sub CPU, just like the main CPU, has a crt0 automatically inserted by
  the build process, and this made up the vast majority of the ARM7 portion
  of the .nds file.</p>
  <p>Therefore, LiraNuna took the step of subverting a part of the build process,
  by deleting the result of the ARM7 compilation, and replacing it with a
  straight binary file, encoding the infinite-loop opcode.</p>
  <samp>
   <h3>ARM7 cut-down: Final binary</h3>
   <pre>0000   FE FF FF EA</pre>
  </samp>
  <p>That left the overall binary at around 4KB. Still plenty of room for
  improvement, I thought.</p>
  <h2>The Next Step: Assembly</h2>
  <p>The main code was still in C, and compiled to Thumb binary. Stepping
  through that in DSemu's debugger, I noticed a few odd things introduced by
  the compiler, that seemed to do very little; values being left-shifted and
  then right-shifted again, to no overall effect, and similar oddities.
  So, the next logical step was to write that portion without the intervention
  of the compiler, in assembly.</p>
  <p>LiraNuna put together a first attempt at an assembly version of the
  program, as follows.</p>
  <samp>
   <h3>ARM9 cut-down: First run</h3>
   <pre>main:
		@ sets POWER_CR
	mov r0, #0x4000000
	orr r0, r0, #0x300
	orr r0, r0, #0x4
	mov r1, #0x3
	str r1, [r0]
 
		@ sets mode
	mov r0, #0x04000000
	mov r1, #0x00020000
	str r1, [r0]
 
		@ sets VRAM bank a
	mov r0, #0x04000000
	add r0, r0, #0x240
	mov r1, #0x80
	strb r1, [r0]
 
		@ loop
	mov r0, #0x06800000
	mov r1, #0x1F
	orr r1, r1, #0x8000
	mov r2, #0x18000
 
	filloop:
		strh r1, [r0], #0x1
		subs r2, r2, #0x1
		bne filloop
 
	lforever:
      b lforever
   </pre>
  </samp>
  <p>When compiled up, that definitely made a difference; the overall ROM size
  dropped to approximately 1.5KB. However, I started to have an inkling that
  we could do better. And that's when pepsiman piped up with a suggestion:
  place the code <em>inside</em> the .nds header.</p>
  <h2>Going deeper: Inside the .nds file</h2>
  <p>What did pepsiman mean by that? In order to understand that, it's important
  to know what a .nds ROM looks like, on the inside.</p>
  <table>
   <thead><tr><th>File offset</th><th>Component</th></tr></thead>
   <tbody>
    <tr><td>0000</td><td>NDS ROM header (512 bytes)</td></tr>
    <tr><td>0200</td><td>ARM9 binary</td></tr>
    <tr><td>0200+ARM9</td><td>ARM7 binary</td></tr>
    <tr><td>0200+both</td><td>Optional file table</td></tr>
   </tbody>
  </table>
  <p>The conventional layout dictates that the main CPU's binary be placed
  after the header, and the sub CPU's binary after that. However, that doesn't
  have to hold true all the time; the order can be swapped, blank space can be
  inserted between the binaries, or after them.</p>
  <p>That's all well and good, but <em>inside</em> the header? In order to
  understand that, it's required to look inside that top chunk of the file:
  the ROM header.</p>
  <samp>
   <h3>Header structure: ndstool sample output</h3>
   <pre>0x00  Game title                 
0x0C  Game code                  ####
0x10  Maker code                 
0x12  Unit code                  0x00
0x13  Device type                0x00
0x14  Device capacity            0x00 (1 Mbit)
<var>0x15  (8 bytes blank space)</var>
0x1E  ROM version                0x00
0x1F  reserved                   0x04
0x20  ARM9 ROM offset            0x200
0x24  ARM9 entry address         0x2000000
0x28  ARM9 RAM address           0x2000000
0x2C  ARM9 code size             0x3A0
0x30  ARM7 ROM offset            0x600
0x34  ARM7 entry address         0x3800000
0x38  ARM7 RAM address           0x3800000
0x3C  ARM7 code size             0x8
0x40  File name table offset     0x608
0x44  File name table size       0x9
0x48  FAT offset                 0x614
0x4C  FAT size                   0x0
0x50  ARM9 overlay offset        0x0
0x54  ARM9 overlay size          0x0
0x58  ARM7 overlay offset        0x0
0x5C  ARM7 overlay size          0x0
0x60  ROM control info 1         0x00586000
0x64  ROM control info 2         0x001808F8
0x68  Icon/title offset          0x0
0x6C  Secure area CRC            0x0000 (-, homebrew)
0x6E  ROM control info 3         0x0000
<var>0x70  (16 bytes blank space)</var>
0x80  Application end offset     0x00000000
0x84  ROM header size            0x00000200
<var>0x88  (36 bytes blank space)</var>
0xAC  PassMe autoboot detect     0x53534150 ("PASS")
<var>0xB0  (16 bytes blank space)</var>
0xC0  Nintendo Logo (156 bytes)
0x15C Logo CRC                   0x9E1A (OK)
0x15E Header CRC                 0xC9D3 (OK)
<var>0x160 (160 bytes blank space)</var></pre>
  </samp>
  <p>The entries highlighted red indicate regions of empty space in the
  header structure. These are normally left behind during the construction
  of the format, to allow for expansion. In this case, however, it's
  possible to make use of the blank regions in the header for the purposes
  of holding code.</p>
  <p>From looking at the above output, it's simple to see that the structure
  of the .nds file as a whole is dictated by the entries in this header.
  The fact that the ARM9 binary follows the header is simply due to the setting
  of "ARM9 ROM offset" to <code>0x200</code>, which is the first byte in the
  file after the header. Similarly, the ARM7 code following the ARM9 is a
  simple effect of the "ARM7 ROM offset" being set to <code>0x600</code>, which
  corresponds to an offset in the file of 1.5KB.</p>
  <p>Simply by changing the "ROM offset" values in this header, it's possible
  to change the point from which the code for the CPUs is loaded, from the
  default location after the header to somewhere inside the header; overwrite
  the zeros in that position with ARM opcodes, and load from there. It seemed
  a good idea by pepsiman, and viable.</p>
  <p>LiraNuna's ARM9 code seemed quite short, but I thought I could go one
  better, shrinking the code down further.</p>
  <samp>
   <h3>ARM9 cut-down: Second run</h3>
   <pre>main:
    mov r0,#0x04000000      ; I/O space offset
    mov r1,#0x3             ; Both screens on
    mov r2,#0x00020000      ; Framebuffer mode
    mov r3,#0x80            ; VRAM bank A enabled, LCD
 
    str r1,[r0, #0x304]     ; Set POWERCNT
    str r2,[r0]             ;     DISPCNT 
    str r3,[r0, #0x240]     ;     VRAMCNT_A
 
    mov r0,#0x06800000      ; VRAM offset
    mov r1,#31              ; Writing red pixels
    mov r2,#0xC000          ; 96k of them
 
lp: strh r1,[r0],#2         ; Write a pixel
    subs r2,r2,#1           ; Move along one
    bne lp                  ; And loop back if not done

nf: b nf                    ; Sit in an infinite loop to finish
   </pre>
  </samp>
  <p>Once assembled, this code ended up looking like the following.</p>
  <samp>
   <h3>ARM9 cut-down: Assembled binary</h3>
   <pre>0000   01 03 A0 E3   03 10 A0 E3   02 28 A0 E3   80 30 A0 E3
0010   04 13 80 E5   00 20 80 E5   40 32 80 E5   1A 05 A0 E3
0020   1F 10 A0 E3   03 29 A0 E3   B2 10 C0 E0   01 20 52 E2
0030   FC FF FF 1A   FE FF FF EA</pre>
  </samp>
  <p>Definitely a little smaller; now the matter remained of where to put it,
  along with the ARM7 binary of one opcode (<code>EAFFFFFE</code>). The ARM7
  was simple enough: the first region of blank space, 8 bytes, was ample space
  to place this opcode. The ARM7 offset was changed, the size changed to 4,
  and that part was done.</p>
  <p>The ARM9 code was similarly simple to place in: the 160 bytes of free
  space at the end of the header seemed more than enough to stash the binary,
  and all that remained was to modify the ARM9 ROM offset and size.</p>
  <p>And that, it seemed, was that. All the code fit comfortably into the
  header, and the final .nds was just 512 bytes in size. Surely that was all
  that could be done? Not quite.</p>
  <h2>To the core: Repositioning</h2>
  <p>As it turns out, not all 512 bytes of the header are used. The 160 bytes
  on the end are in the header simply by convention; one might as well say
  that the .nds file consists of a 352-byte header, 160 bytes of padding,
  and then the two CPU binaries. Was it possible to fit the 56-byte ARM9
  binary somewhere else inside the header, and eliminate this padding?</p>
  <p>I started by changing the "header size" field at <code>0x84</code> to
  reflect the new size of the header, which would be <code>0x160</code> bytes.
  Then, I started inserting the opcodes, until I had something like this.</p>
  <samp>
   <h3>ARM9 placement: Within the header</h3>
   <pre>0070   01 03 A0 E3   03 10 A0 E3   02 28 A0 E3   80 30 A0 E3
0080   00 00 00 00   A0 01 00 00   04 13 80 E5   00 20 80 E5
0090   40 32 80 E5   1A 05 A0 E3   1F 10 A0 E3   03 29 A0 E3
00A0   B2 10 C0 E0   01 20 52 E2   FC FF FF 1A   50 41 53 53
00B0   FE FF FF EA   00 00 00 00   00 00 00 00   00 00 00 00</pre>
  </samp>
  <p>The fields in the header at 0x80, 0x84 and 0xAC can be seen, nestled
  within the ARM9 code. Now, this is quite a problem; if those values correspond
  to valid opcodes, they may be executed, and that might prove disastrous for
  the state of the program.</p>
  <p>A disassembly was called for. I loaded up the new binary in DSemu, and
  the debugger gave the following output:</p>
  <samp>
   <h3>ARM9 cut-down: Code after insertion</h3>
   <pre>    mov r0,#0x04000000     
    mov r1,#0x3            
    mov r2,#0x00020000     
    mov r3,#0x80
    <var>andeq r0, r0, r0</var>
    <var>andeq r0, r0, r0, lsr #3</var>
    str r1,[r0, #0x304]    
    str r2,[r0]            
    str r3,[r0, #0x240]    
    mov r0,#0x06800000     
    mov r1,#31             
    mov r2,#0xC000
lp: strh r1,[r0],#2        
    subs r2,r2,#1          
    bne lp                 
    <var>cmppls r3, #0x14</var>
nf: b nf                   
   </pre>
  </samp>
  <p>It seems I was fortunate. The first two AND statements will never be
  executed, since they depend on the ZERO flag being set, and said flag is
  not set by the instructions above. As for the CMP, it slots into place
  after the VRAM-writing loop, which is indeed fortunate; if the CMP had
  fallen before the BNE, the loop may have executed forever, eventually
  running out of VRAM to write to.</p>
  <p>Surprisingly fortunate, I thought; I hadn't planned for such a consequence,
  and it had simply come about due to the size and structure of the code.
  Either way, I wasn't about to complain.</p>
  <h2>Conclusion</h2>
  <p>So, there we have it. The smallest .nds file you're ever likely to see,
  which still does something. The ARM7 sticks itself into an infinite loop,
  and the ARM9 fills the main-core framebuffer with red before entering its
  own infinite loop. I eventually got my wish, of a small framebuffer-testing
  demo, but it was fun to get there.</p>
  <samp>
   <h3>Final binary: 352 bytes</h3>
   <pre>
0000   4E 44 53 2E   54 69 6E 79   46 42 00 00   23 23 23 23  NDS.TinyFB..####
0010   00 00 00 00   00 00 <s>FE FF   FF EA</s> 00 00   00 00 00 04  ................
0020   70 00 00 00   00 00 00 02   00 00 00 02   44 00 00 00  p...........D...
0030   16 00 00 00   00 00 80 03   00 00 80 03   04 00 00 00  ................
0040   A0 01 00 00   00 00 00 00   A0 01 00 00   00 00 00 00  ................
0050   00 00 00 00   00 00 00 00   00 00 00 00   00 00 00 00  ................
0060   00 60 58 00   F8 08 18 00   00 00 00 00   00 00 00 00  .`X.............
0070   <s>01 03 A0 E3   03 10 A0 E3   02 28 A0 E3   80 30 A0 E3</s>  .........(...0..
0080   00 00 00 00   A0 01 00 00   <s>04 13 80 E5   00 20 80 E5</s>  ............. ..
0090   <s>40 32 80 E5   1A 05 A0 E3   1F 10 A0 E3   03 29 A0 E3</s>  @2...........)..
00A0   <s>B2 10 C0 E0   01 20 52 E2   FC FF FF 1A</s>   50 41 53 53  ..... R.....PASS
00B0   <s>FE FF FF EA</s>   00 00 00 00   00 00 00 00   00 00 00 00  ................

00C0   C8 60 4F E2   01 70 8F E2   17 FF 2F E1   12 4F 11 48  .`O..p..../..O.H
00D0   12 4C 20 60   64 60 7C 62   30 1C 39 1C   10 4A 00 F0  .L `d`|b0.9..J..
00E0   14 F8 30 6A   80 19 B1 6A   F2 6A 00 F0   0B F8 30 6B  ..0j...j.j....0k
00F0   80 19 B1 6B   F2 6B 00 F0   08 F8 70 6A   77 6B 07 4C  ...k.k....pjwk.L
0100   60 60 38 47   07 4B D2 18   9A 43 07 4B   92 08 D2 18  ``8G.K...C.K....
0110   0C DF F7 46   04 F0 1F E5   00 FE 7F 02   F0 FF 7F 02  ...F............
0120   F0 01 00 00   FF 01 00 00   00 00 00 04   00 00 00 00  ................
0130   00 00 00 00   00 00 00 00   00 00 00 00   00 00 00 00  ................
0140   00 00 00 00   00 00 00 00   00 00 00 00   00 00 00 00  ................
0150   00 00 00 00   00 00 00 00   00 00 00 00   1A 9E 7B EB  ..............{.
   </pre>
  </samp>
  <p><a href='http://imrannazar.com/content/files/TinyFB.nds'>http://imrannazar.com/content/files/TinyFB.nds</a></p>
  <p>Two9A, with thanks to LiraNuna and pepsiman</p>
 ]]></content>
</entry>
</feed>
