Digital Adventures

Notes on programmable logic, tabletop games & other stuff


| Comments

It’s really easy to write roundup posts, so here you have it. Things I’ve been working on lately:

  • The 9 to 5, which is has expanded from exclusively Enterprise Java™ to C#.NET, which is actually surprisingly nice to use.
  • Playing a lore bending time traveler in World of Warcraft: Warlords of Draenor.
  • Messing around with Ring/Compojure, since apparently I’m a glutton for punishment in the form of deploying Java web applications.
  • Explaining board game rules, playing board games, and visiting board game shops. Who knew there were so many of them here in Austin? Don’t worry Dragon’s Lair, you’re still my favorite.
  • Reading Pathfinder Tales, currently City of the Fallen Sky by Tim Pratt.
  • Reading Horus Rising. I’ve been enjoying lore/in universe books lately, okay?

Tabletop Night, or How I Managed to Play Ticket to Ride Three Times in a Month

| Comments

Partially inspired by Wil Wheaton’s Tabletop series, Hannah and I host a (almost) weekly tabletop game night. The players and games vary, but the underestimation of the game time does not. Oh yes, and it’s pretty consistently entertaining as well.

Some notes on the games that we’ve played:

  • Ticket to Ride: My go-to game for new players. Why? I like trains, so the theme never gets old, the game is for ages 8+, so it works well for my similarly aged peers, and the rule book is just two pages in length. The only drawback is the player count (2 to 5); it doesn’t work out well for two people due to not enough competition, and has a hard limit of 5 players, which prevents pulling it out when we invite two people and they each bring +1s.
  • Formula D: Is a game that desperately needs a catch-up mechanic. While I’m not a fan of rubber-banding in racing video games, Formula D isn’t much fun when you mess up the first long corner on the first lap and then have to spend the rest of the game limping along trying to not have your tires catch on fire. Bonus points for realism, I suppose.
  • Power Grid: Boy, these rules are lengthy.
  • Eldar Elder Sign: Likely the oldest game in our collection and my second favorite. Requires careful adherence to the rules or else the challenge disappears.
  • Betrayal at House on the Hill: Hooray, multiple endings with one or more betrayers. A good game, though not terribly engaging when it isn’t your turn. Not very much fun if the betrayal happens in less than four or so turns or when the room pile is nearly empty.
  • Munchkin (Adventure Time theme optional): The longest card game I’ve ever played.
  • Coup: I will steal from you and then I will use that money to assassinate you. Requires careful wording which may be challenging for some (I can’t remember how many times there was confusion about having/not an assassin or having/not a contessa to block it).
  • Battlelore: Bought it, then realized I just wanted to play Warhammer 40k. More on that later.
  • Mille Bornes: Coup fourré! Semi-abstract card based driving with retro-fabulous 70s artwork. Was fun when I played it when I was 10, still fun now.

Skillbook and Flight-history

| Comments

It has been a month since I last made a commit to skillbook. While my interest in the project was revitalized for a few months by switching from plain ol’ javascript to the more entertaining evented Flight, my waning interest in EVE online itself has put a damper on any further development efforts. It’s hard to work on a program that solves a problem that you don’t face anymore. I won’t say that it is impossible, just that the motivator of “wow, this existing solution sucks” is a very good one.

I’m still going to keep my EVE account subscribed, though. I’ll play/pay for skill queue online so that when the mood strikes me I’ll be pleasantly surprised at how many things I can do with these skills. That’s the idea, anyhow.

The code for skillbook can be found here. MIT licensed, requires Python 3, Celery, Postgre SQL, Redis, and bower for development. While developing the frontend for skillbook, the need for push state arose. At the time, there wasn’t any good flightjs related solution, so I made one. It supports two way binding: navigate to a defined URL and it triggers an event, or trigger an event and the URL will change, with optional parameterization in both cases. Someone even wrote tests for the library which was unexpected and very nice of them.

Edit 11/04:

With the advent of unlimited (ish) queues in EVE, I have decided to take the production skillbook website ( offline. I still haven’t played more than a few hours of EVE since this was written more than a month ago, and I don’t see that situation changing anytime soon. Secondly, this change to queue lengths makes the only functional part of skillbook obsolete, viewing skills and the current skill queue.

But I still have that domain for a year (or two). Coming soon:, a private link shortener.


| Comments

Over the past few days I’ve been working on The Eudyptula Challenge. For those keeping score at home, this is a momentary break from working on skillbook which, in turn, was a diversion from working on Taliesin (I just noticed that GitHub has a woefully out of date copy). In any case, Eudyptula is a genus containing two species of penguins that are commonly found in Australia, Tasmania, New Zealand and the Chatham Islands. On the other hand, the Eudyptula Challenge is “a series of programming exercises for the Linux kernel, that start from a very basic “Hello world” kernel module, moving on up in complexity to getting patches accepted into the main Linux kernel source tree.”

Sounds fun, right?

With two tasks under my belt, I can say that it is. Completing the first task also necessitated setting up msmtp+fetchmail+mutt as the grading script doesn’t accept either html email or non-plaintext attachments (web-based Gmail defaults to html bodies and sends all attachments as base64 encoded). One of the challenge rules is to not talk about the solutions or the tasks, so I won’t go into any more detail here.

And with that, the email for task 3 just appeared in my inbox.


| Comments

Things I’ve been working on lately:

  • The 9 to 5, which is almost exclusively Enterprise Java™
  • Playing EVE Online.
  • Contributing to pyhole, a mapping tool for EVE that was created by a friend and member of the same in game corporation. For those unfamiliar with EVE, this tool is used to assist in navigating ephemeral wormhole connections between wormhole systems and known solar systems.
  • Contributing to ykill (which is visible publicly here), another tool for EVE created by the same person as pyhole. For those unfamiliar with EVE, think of this tool as a big scorecard. Destroy someone’s ship? It’ll show up there, along with all of the times that you’ve lost ships.
  • Creating skillbook, a web-based tool for tracking skills and skill queues in EVE. Most of my non-working hours for the past few weeks have gone into this project. I’ve attached a screenshot of it at the bottom of this post, click to make it larger.
  • Reading Ruby Under a Microscope and Doing Data Science. Out of the two, I’ve read more of Ruby because there’s less math to wade through during reading time (that is, 12 AM+)

skillbook image

(some parts of this image have been altered, since that’s not my real name)


| Comments

Not just the summer home of Frank Lloyd Wright. Taliesin is the whimsical name that I have given my soft processor implementation of the iota architecture. For those not familiar with the Iota ISA, I’m not really surprised; I made it up. Check the previous post for more details about the Iota ISA.

Expect a more lengthy writeup in the future; for now, check it out on Github.


| Comments

Iota is a small, modified Harvard (RISC) architecture that is largely inspired by the MIPS R2000 ISA and the CPU0 teaching ISA. Iota is 32-bit register machine. Furthermore, all memory accessed must be 4 byte aligned and there is no concept of loading or storing bytes and halfwords. This was done to simplify the implementation of the memory management unit and to further reduce the number of opcodes.

Memory and Registers

As mentioned before, all memory accesses store or return 32 bits and must be 4 byte aligned. The register file contains 16 general purpose registers (denoted r[0] through r[15]) with register 0 containing the fixed value of 0 at all times. By convention, r[15] is used as the return address from subroutines, and r[14] is used for the return address from interrupt handlers. There are two special purpose registers: the program counter (PC) and the condition register (CR). The condition register is 32 bits, albeit only the lower four bits are currently utilized.

|----|------------------------|----|    Condition Register
|HRRR|  Reserved (24 bits)    |ICZN|
  • CR[Z] is set when the previous modifying instruction resulted in a zero
  • CR[N] is set when the previous modifying instruction resulted in a negative value
  • CR[C] is set when the previous modifying instruction resulted in a carry out
  • CR[I] is set during an interrupt routine
  • CR[H] is set when the processor has halted
  • CR[R] is a three bit field that contains the reason for the processor halt


Instructions come in three formats: R, I, and J. R-type instructions take all operands from registers and store it in another register. I-type instructions have two registers (source and destination) and a larger field for a 16-bit immediate value. Finally, J-type instructions have a 24-bit offset field that specifies a jump offset.


|--------|------------------------|     J-Type
| OP (8) |    Jump offset (24)    |

|--------|----|----|----------------|   I-Type
| OP (8) |Rd 4|Rs 4| Immediate (16) |

|--------|----|----|----|------------|  R-Type
| OP (8) |Rd 4|Ra 4|Rb 4|Secondary 12|
Type Mnemonic Opcode / Secondary Description Syntax Operation CR Modified?
- TRAP 00 / xxx Trap operation. Raises an ‘invalid operation’ exception TRAP No
R RET 01 / 000 Return from subroutine RET PC <= r[15] No
R J 01 / 001 Jump to location stored in register J Rd PC <= Ra No
R ADD 01 / 002 Add ADD Rd, Ra, Rb Rd <= Ra + Rb Yes
R ADDu 01 / 003 Add Unsigned ADDu Rd, Ra, Rb Rd <= Ra + Rb Yes
R SUB 01 / 004 Subtract SUB Rd, Ra, Rb Rd <= Ra - Rb Yes
R OR 01 / 005 Logical OR OR Rd, Ra, Rb Rd <= Ra | Rb Yes
R XOR 01 / 006 Logical XOR XOR Rd, Ra, Rb Rd <= Ra ^ Rb Yes
R AND 01 / 007 Logical AND AND Rd, Ra, Rb Rd <= Ra & Rb Yes
R NOT 01 / 008 Logical inverse NOT Rd, Ra Rd <= ~Ra Yes
R LSL 01 / 009 Logical shift left. Drop leftmost and insert zeros at right LSL Rd, Ra, Rb Rd <= Ra << Rb Yes
R LSR 01 / 00A Logical shift right. Drop rightmost and insert zeros at left LSR Rd, Ra, Rb Rd <= Ra >> Rb Yes
R ASR 01 / 00B Arithmetic shift right. Drop rightmost and keep sign bit of Ra LSR Rd, Ra, Rb Rd <= (h80000000&Ra)|Ra >> Rb Yes
R CMP 01 / 00C Compare two registers. Sets CR[Z] if Ra, Rb equal. Sets CR[N] if Ra < Rb CMP Ra, Rb CR <= (Ra - Imm16)? Yes
R SW 01 / 00D Store word (4 byte aligned) SW Rd, Ra, Rb MEM[Ra+Rb] <= Rd No
R LW 01 / 00E Load Word LSR Rd, Ra, Rb Rd <= MEM[Ra+Rb] No
I ADDi 02 / - Add Immediate ADDi Rd, Ra, Imm16 Rd <= Ra + Imm16 Yes
I ADDiu 03 / - Add Immediate Unsigned ADDiu Rd, Ra, Imm16 Rd <= Ra + Imm16 Yes
I 04 / - Unused
I ORi 05 / - Logical OR with Immediate ORi Rd, Ra, Imm16 Rd <= Ra | Imm16 Yes
I XORi 06 / - Logical XOR with Immediate XORi Rd, Ra, Imm16 Rd <= Ra ^ Imm16 Yes
I ANDi 07 / - Logical AND with Immediate ANDi Rd, Ra, Imm16 Rd <= Ra & Imm16 Yes
I 08 / - Unused
I LSLi 09 / - Logical Shift Left with Immediate. Drop leftmost and insert zeros at right LSLi Rd, Ra, Imm16 Rd <= Ra << Imm16 Yes
I LSRi 0A / - Logical Shift Right with Immediate. Drop rightmost and insert zeros at left LSRi Rd, Ra, Imm16 Rd <= Ra >> Imm16 Yes
I ASRi 0B / - Arithmetic Shift Right with Immediate. Drop rightmost and keep sign bit of Ra ASRi Rd, Ra, Imm16 Rd <= (h80000000&Ra)|Ra >> Imm16 Yes
I CMP 0C / - Compare with Immediate CMP Ra, Imm16 CR <= (Ra - Imm16)? Yes
I SW 0D / - Store word (4 byte aligned) SW Rd, Ra, Imm16 MEM[Ra+Imm16] <= Rd No
I LW 0E / - Load Word LSR Rd, Ra, Imm16 Rd <= MEM[Ra+Imm16] No
J JEQ 10 / - Jump if EQual JEQ Off24 if CR[Z], PC <= PC + Off24 No
J JNE 11 / - Jump if Not Equal JNE Off24 if not CR[Z], PC <= PC + Off24 No
J JGT 12 / - Jump if Greater Than JGT Off24 if CR[N], PC <= PC + Off24 No
J JLT 13 / - Jump if Less Than JLT Off24 if not CR[N], PC <= PC + Off24 No
J JLE 14 / - Jump if Less than or Equal JLE Off24 if CR[E] or CR[N], PC <= PC + Off24 No
J JGE 15 / - Jump if Greater than or Equal JGE Off24 if CR[E] or not CR[N], PC <= PC + Off24 No
J JAL 16 / - Jump to subroutine and Link JAL Off24 R[31] <= PC, PC <= PC + Off24 No
J SWI 20 / - Software Interrupt SWI Off24 CR[I] <= 1, R[14] <= PC, PC <= PC + Off24 Yes
J RTI 21 / - Return from Interrupt RTI CR[I] <= 0, PC <= R[14] Yes

Math Extension

Type Mnemonic Opcode / Secondary Description Syntax Operation CR Modified?
R MTLO 03 / 01 Load a register into the lower half of the coprocessor register MTLO Ra R[LO] <= Ra No
R MTHI 03 / 02 Load a register into the upper half of the coprocessor register MTHi Ra R[HI] <= Ra No
R MFLO 03 / 03 Load a register from the lower portion of the coprocessor register. MFLO Rd Rd <= R[LO] No
R MFHI 03 / 04 Load a register from the upper portion of the coprocessor register. MFHI Rd Rd <= R[HI] No
R MULT 03 / 06 Multiply Ra and Rb, store in the coprocessor registers MULT Ra, Rb {LO,HI] <= Ra*Rb No
R MULTU 03 / 05 Multiply unsigned Ra and Rb, store in the coprocessor registers MULTU Ra, Rb {LO,HI] <= Ra*Rb No

Implementation Recommendations

While Iota has an upcoming reference implementation, Taliesin, it is prudent to outline a implementation of this processor.

Baseline features:

  • 5 Pipeline stages: Fetch, Decode, Execute, Memory, Writeback
  • No forwarding, block on hazard
  • Bubble insertion on fetch

Recommended features:

  • 5 Pipeline stages
  • Branch prediction (Two-level adaptive)
  • Register forwarding
  • Split D- and I-caches
  • Multiply and divide implementation

While Taliesin is still a work in progress, it aims to fulfill all of the recommended features of the Iota architecture.

Time Crunch

| Comments

Why I haven’t posted in a while:

Plus standard end-of-semester busyness.


| Comments

Apparently my Google-fu isn’t as good as I would like to believe. As it turns out, this guy has a nice series of tutorials about the Spartan Microboard.

We’re Number… 48!

| Comments

I’ll be pushing all of the code for these blog entries to a GitHub repository. This is good for both of us, actually. Good for you in that you don’t have to endlessly copy/paste code snippets from this site. Good for me in that I won’t have to put the full source of every Verilog file in the body of the blog post.

Also, no guarantees that the .xise (Xilinx Project Navigator) file will work properly for any project.