Wishful Coding

Didn't you ever wish your computer understood you?

Does a compiler use all x86 instructions?

On the Z80 CPU there are so few registers and instructions that you can easily know and use them all and wish there were more of them. However, half of the time it feels like the only on you really use is ld. I imagine that if ld took half the number of clock cycles, average code would run twice as fast.

In modern x86(_64) there are so many that I even wonder if my compiler knows and uses them all, and how often. To get an impression, I ran this one-liner:

objdump -d /usr/bin/* | cut -f3 | grep -oE "^[a-z]+" | sort | uniq -c

Full output here. In total I counted 411 different mnemonics, topped by 15891451 mov instructions and a very long tail of instructions that only occur once or twice.

There are 33% mov instructions. Combined with callq, je, and lea making up over half of all code.

Opcode pie chart

Between the expected compare and jump instructions, “Load Effective Address”, “eXclusive OR” and “No OPeration” surprised me. Of course nop is probably padding and xor is the best way to zero a register, but I have no clue why there are so many lea everywhere.

Nobody really seems to know how many x86 instructions there are, but someone counted 678, meaning there are over 200 instructions that do not occur even once in all the code in my /usr/bin.

It would be interesting to break it down further in “normal” instructions, SIMD instructions, other optimizations, and special purpose instructions… if anyone can be bothered categorizing 600+ instructions.

Pepijn de Vos

Game Boy Paint

After my various Pokemon hacks and reading portions of the Pokemon Red source code, it occured to me it would be fun to write my own game from scratch. But in typical fashion I got sidetracked thinking about the engine, levels, sounds and graphics.

I decided that “obviously” the best thing to do was to write editors for the game first, starting with the paint program.

I did most of this away from the internet, giving a more authentic feeling of having just the assembler between you and the machine and just the manual to guide you. (I did ocasioanlly visit #pret for advice)

I could not find much in terms of complete tutorials. I bascially relied on 4 major resources.

  • pandoc lots of info about the hardware
  • CPU manual all the details about the instruction set
  • GALP sample code and hardware defines
  • pokered large corpus of working code and tooling to steal and learn from

I figured I would dedicate one tile set entirely to the canvas and the other on to the UI. I’d use the background tiles for the canvas, the window tiles for the UI and the sprites for the cursor.

Until I found the window layer is opaque and shares the same tile set as the background. It even turns out the two tile sets partially overlap, giving me only half a tile set for the UI.

In the end I did not use the window layer, but switched the tile set used by the background during hblank, so that the top half of the background is drawn using the first tile set and the bottom with the other set. A few hundred lines of assembly later…

gbg screenshot

With the UI basically working I started actually drawing tiles. This involves finding the correct tile, the correct row in that tile, and then flipping two bits in the 2 bytes comprising that row. Dozens of lines of assembly later…

gbg screenshot

Drawing bigger lines is a matter of flipping more bits. To do this I defined a pattern like %11110000 that I would roll to the correct position and and with the tile. This does kind of break when you draw a big brush past a tile edge, but that’s a problem for later.

gbg screenshot

This is what I love about assembly game development. Instead of a nice error message you get this glorious glitch on your screen and you have no idea what you did wrong.

The Game Boy has this weird two bits per pixel format where all significant bit for a pixel are in byte one and the least significant bit for the pixel is in the second byte. The loop that was supposed to fill a square with the selected color wasn’t exactly right.

gbg screenshot

Fixing that loop allowed me to draw in various colors and sizes, but large brushes still overflow to an adjacent tile.

gbg screenshot

I chose to self-align brushes, so your 2x2 brush moves with 2px increments and the 8x8 brush moves at 8px increments.

gbg screenshot

Finally, I implemented loading and saving to SRAM. With the aid of the pokered tools, a simple make export converts your saved tile set to a png, and with a bit of fiddling you can also convert a random flower picture to a tile set and paint your name on it.

gbg screenshot

Whew, that was harder than expected. It was challenging and fun and I learned a lot, but I’m not sure if I’ll write a full game this way. The full 700+ lines of assembly can be found here.

It was shocking to me to find how limited Z80 assembly is. There are only a hand full of registers, and a hand full of valid combinations. Many operations (math, literal load, address load) only work with a as the source/destination. 16-bit addition (together with inc the only 16-bit ops) only works with hl and the stack pointer.

It’s easy to see that in this environment, hand-written assembly outperforms C. With so few ops and registers, C is bound to push a lot of local variables to the stack, and unlikely to make efficient use of high-ram and registers. It’s also very easy to do things in C that have no hardware equivalent, such as multiplication/division and anything with signed or 16-bit numbers.

On the other hand it’s also easy to see that on modern platforms and large code bases, C beats assembly in every possible way. Maybe even on a Game Boy an indie(you know, for individual) game is more feasible using C, when used carefully.

Pepijn de Vos

Pokemon Gringo

In Puerto Rico, folk etymology states that the word “gringo” originated from the English words “green” and “go” referring to the desire of some locals to have the U.S. military (who allegedly wore green uniforms) leave the island by telling them: “Green, go!” 1

As a long-time Pokemon fan, I got really excited when I heard about Pokemon Go. But excitement quickly turned into disappointment as I found out the Android runtime on my Blackberry does not support the required API version.

So I took my Gameboy to play some good old Pokemon Red, when a thought struck me. How hard would it be to add a GPS to TCPoke and modify pokered to allow TCPoke to initiate wild Pokemon battles?

I had previously read parts of pokered to understand the serial protocol I needed to make TCPoke, but I never actually wrote Z80 assembly. Luckily, it turned out to be relatively easy. After a few hours I already added an extra menu item to the Cable Club, and a few hours later the menu actually did something.

It’s kind of glitchy and broken, but the diff is surprisingly small.

GBG simulation of Pokemon Gringo

Next up I modified Bill’s Arduino state machine to recognize the new menu item and added some GPS code. Again, it took a few hours, but the diff is again relatively small. (Except for this huge chunk of Pokemon level and location data I extracted from pokered)

But at this point I only had the code running in BGB/Gambatte (which I even modified to emulate BIll’s Arduino), so I had to order a flash cart to load the modified ROM onto my Gameboy. After camping on the doormat for a week, ignoring friends and family and only leaving the house outside delivery hours, today I finally received the cart and could begin testing on real hardware.

First boot

It almost worked on the first try! There were some small bugs in the Arduino code, which I could not test up to this point. Then I did a few rounds around the block, carrying my whole laptop+Teensy+Gameboy around for debugging. The first Pokemon I encountered made me almost jump into the air from excitement and surprise.

Pokemon Gringo really captures that feeling of surprise when you’re happily trodding along when suddenly…

GBG simulation of Pokemon Gringo

For the best experience I recommend turning up the volume all the way and physically walking though tall grass.

Here is a video of me walking to the supermarket with my new gear.

Pepijn de Vos