Gameboy Pocket Color

Background

Back in January of this year, I picked up a Poco Kit from Natalie the nerd, hoping to be able to convert a damaged Gameboy Color that I got for a song on ebay a while back. In my opinion, the Gameboy Pocket (GBP) is a far superior form factor to the Gameboy Color (GBC). Unfortunately, the GBC’s board is slightly too tall to fit inside a GBP’s case and the buttons don’t line up with the button holes in case, either.

Note: The Gameboy Pocket is generally referred to as the MGB, since that’s the model number that nintendo used. But I’ll refer to it here as GBP for simplicity.

So the “simplest” solution is to slice off the bottom of a GBC, right below the cartridge slot, and do the same to a GBP board. Then perform the necessary wiring between them. There’s a couple of other considerations, since the GBP uses some extra electronics for dealing with button presses.

The bottom half of this damaged GBC I had was in really rough shape, but the top half was in perfect condition, which means that I had the perfect piece of hardware for this project.

The bottom, damaged half of a Gameboy Color

Natalie’s kit includes 2 parts: a bottom half which needs a few parts from the donor GBC (the power and headphone jacks and a power regulator board) and a ribbon cable which lines up with the top GBC half. By using Natalie’s kit, you only need a donor GBC and not an additional donor GBP.

Unfortunately, I screwed up somewhere and the ribbon cable didn’t align the two parts properly when putting the shell back together. I don’t know what I did wrong, but some of the ribbon cable tore and I decided to give up on that approach.

The ribbon kinda folded on itself

Since beginning this project, Natalie released a v2 of the kit, but I had already dropped a pretty significant amount of money on the first version, so I opted to hand-wire this myself and avoid sinking more money into the project.

Insides

I removed the ribon cable and started looking at what I needed to do to complete this project. Basically, I just had to solder in 22 wires in total:

  • 2 for the power switch
  • 4 for the LCD
  • 16 to connect the bottom board to the top board

I cut up some wrapping wire and got started.

My skills are still improving and I’m trying to get better about strategizing how I approach these types of things. Part of this is getting better at routing the wires, but another part is just trying to not be so sloppy. This is as neat as I could manage.

Soldering in the wires for the speaker, buttons and power
Re-routing the wires as cleanly as I could manage

While doing this I took meticulous notes so I’d be sure to solder the correct wires to the correct pads. I spent a lot of time verifying continuity to ensure I had no bridges.

The end results was this:

The button-side of the board, where all the wires are visible
The rear-facing portion. I'm very satisfied with my power button wire routing, here.

Finished project

So this is the finished project:

The front of the completed Gameboy Pocket Color
And the back, with a spiffy sticker

Overall, I’m pretty happy with this. It works, but not perfectly.

The power switch is a little sticky. The power switch had to be relocated to the top since the GBP has the switch on top, where the GBC’s IR LEDs live. This requird desoldering the IR LEDs and power switch and using Natalie’s mounting board to mount the switch in its new location. While doing this, the switch was filled with flux and got kinda gross. I did open it up and attempt to clean it, but the switch really never felt the same after that. I actually ruined another switch trying to do this and the switch that wound up in the final product is from another donor GBC that I have.

Additionally, the up and down D-pad buttons aren’t terribly responsive. I’m not sure what’s going on, but I’m going to need to open it up again, and maybe clean it or something, but that’s a task for another day.

The power button is also reversed. The GBP case labels the switch in the off position when it’s switched towards the left edge of the case, but in my case, that’s the ON position. I’m not sure if that’s expected or not, but it caught me off-guard.

Final thoughts

If I were to take this project on again, I’d plan even better for the how the wires are routed, for sure. I’d really like to be able to get some super-clean wire routing done where no wires have to cross over and potentially get crushed.

I’d also opt to use a different type of wire. The wire I used is pretty thin, solid-core wrapping wire, but it’s delicate and can break if bent too many times. That makes it a really poor fit for this type of project. I need to invest in some better wire. Like, the wire that came with the LCD is a lot more flexible AND it’s thinner. I’d definitely go that route for some of this if I were to do it again.

I also really need to practice removing power switches and cleaning them. For next time.

Overall, though, I am happy with this project and I’m super happy with the case I chose for it. It’s really attractive.


Portland Retro 2024

Last weekend I went to Portland, OR for the Portland Retro Gaming Expo. This was my second time going and I managed to spend a little less money this year than last year, but at the same time, it felt like a lot of prices were a bit higher this year.

For me, the best part of the trip, besides being able to haggle on prices a little, is seeing friends that I basically only see at the expo. It was great seeing Gene and Candice as well as my buddy Dennis who comes out from NJ.

Luckily, I did manage to find some good deals, though. I managed to pick up an N64 (just the system, no peripherals or even a power supply) for $50, a Game Gear that is having some display issues for $30 and a GBA in pretty good condition for $45. Later in the expo, I found a power supply for the N64, which took a lot of hunting.

My initial haul. N64, Game Gear, a GBA and a smattering of games

I always forget how much grinding is necessary to make progress in Dragon Warrior. It’s been probably 15 years since I last played it. But I have very fond memories of grinding into the wee hours of the morning on this game when I was like 9 years old.

N64 Majora's Mask -- a light breeze will make this fall apart

I’ve been working on filling out my Zelda cartridge collection, so I got my hands on A Link to the Past for a decent price, Oracle of Seasons in bad condition, but a good price and even Majora’s Mask for a decent price. Unfortunately, the Majora’s Mask cart is crumbling and doesn’t even hold together, which I didn’t notice until I got it home. I need to superglue a screw post and another support to get it back together.

So I think my plan is to recap the Game Gear and hopefully get that working again, do an HDMI mod to the n64 so I can actually play some games and then do a big upgrade to the GBA, adding a nice screen and maybe a new shell. I’ve been on the fence about whether I actually want to do a USBC upgrade to my handhelds anymore. At least, the various Game Boys. It’s nice, but it’s also kind of destructive and who knows if in the future there will be something better than the USB-C thing. But the rechargeable lithium poly batteries are pretty nice. So I dunno what I’ll do.

I’ve got a stack of DS and Gameboys that I want to hack on, but just haven’t had the time. But maybe it’s time to do it.

Lastly, I managed to get my hands on some goofy carts. Namely the old Atari ET cart and some meme-worthy GBA carts.

ET for the Atari 2600
I got these as a joke. I swear.

Anyway, I’ll hopefully post something when I get some work done on the N64 or get the GameGear working again.


Arch Update Woes

The main machine I use for any personal projects is currently a Lenovo Thinkpad X1 Carbon running ArchLinux. I’ve been using this machine for almost exactly 4 years at this point, and although I don’t love it, it’s been a good workhorse for me.

One of the big issues that I’ve run into in the past was that an update sometimes screws the system up. I had a few months where the graphical interface would occasionally freeze, which turned out to be caused by a vulkan driver I’d installed. This took a while to figure out because I’d installed the driver like weeks before the issue cropped up, so initially I thought it was a hardware issue.

Most recently, I did a standard system update, which had some errors along the way. I was using yay as my update tool since it has good AUR support, and even that tool stopped working with an error about not being able to open the libalpm.so.13 shared object file. Additionally, after any update, I generally reboot because some random stuff gets weird: I lose some of my custom keymappings, my key repeat rate resets, docker often stops working. Things like that.

So I reboot and after typing in the password to decrypt the root filesystems, I get:

Please enter passphrase disk Linux LVM (cryptlvm): (no echo)
[  OK  ] Finished Cryptography Setup for cryptlvm.
[  OK  ] Reached target Local Encrypted Volumes.
[  OK  ] Reached target System Initializatoin.
[  OK  ] Reached target Basic System.
[**    ] A start job is running for /dev/MyVolGroup/root (31s / 1min 30s)

Where it then timed out and did not complete the boot/login process.

It turned out that this was caused by a deprecated mkinitcpio hook for sd-lvm2, which I found documented here: https://bugs.archlinux.org/task/69591

I was able to track down this bug by booting off a thumbdrive (luckily I kept really good notes when I set this machine up) and tried to follow some of the steps on the archwiki to set up how the machine boots and got an error when running mkinitcpio -P. A little googling after seeing the error about the unknown hook, I switched the hook name and the machine rebooted fine.

I was a little frustrated and tired when this originally happened, so I ordered a new M3 MacBook Air, which I’m kinda excited to switch to since I’m tired of things breaking and also not having a good email app. Plus I just want my stuff to work and I want a decent keyboard. I love using Linux, and I’m going to miss having a native Docker system, but in the end, the laptop is a tool and it’s best to have the tools work.

My plan for this Thinkpad is to install nixOS which comes with the promise of reproduceable builds, so we’ll see.


Migrate From Tumblr

I recently set up this new blog for myself. In the past I’ve gone through several blogging platforms. LiveJournal was probably my first, followed by Blogger, an experimental jaunt on wordpress for a weekend, then to Tumblr, where I last wrote in 2014. But I really liked some of the content I had on tumblr and they had a way to export all of my posts, so I exported it to json using their API guide.

This site is Hugo, which uses Markdown files as posts and the build process generates static HTML files that I just rsync up to my server running nginx.

Migrating the posts themselves

To convert that JSON export I got from Tumblr into Hugo posts, I wrote a quick bash script.

This script takes a file outfile.json that’s in the current directory and generates a markdown file for each post. It requires bash 4.x (so if you’re on macOS, brew install bash and make sure your PATH uses that one) and jq.

#! /usr/bin/env bash

set -euo pipefail

# output alias URLs as json
get_urls() {
  local id="$1"

  query_with_id "$id" '[.url, .["url-with-slug"]]'
}

# given a post ID, run a jq query against it to read field(s)
query_with_id() {
  local id="$1"; shift

  jq --arg id "$id" '.posts[] | select(.id == $id)' "$file" \
    | jq "$@"
}

file="oldblog.json"

# get all of the post IDs from the json file
ids="$( jq --raw-output '.posts[].id' "$file")"
mapfile -t ids <<< "$ids"

echo "got ${#ids[@]} ids"

# iterate over each post and generate the file
for id in "${ids[@]}"; do
  aliases="$( get_urls "$id" | sed -E 's|https://blog.spike.cx||' )"

  title="$( query_with_id "$id" '.["regular-title"]' )"
  body="$( query_with_id "$id" --raw-output '.["regular-body"]' )"
  slug="$( query_with_id "$id" --raw-output '.slug' )"
  date="$( query_with_id "$id" --raw-output '.["date-gmt"]' )"

  # convert that date into ISO-8601 format
  date="$( date -d "$date" --iso-8601=seconds )"

  outfile="./content/posts/${slug}.md"

  cat <<END > "$outfile"
+++
title = $title
draft = true
date = "$date"
aliases = $aliases
+++

> Note: this post was migrated from my old Tumblr-backed blog

$body
END
done

I did wind up having to massage some of the files. Although I used Markdown for most posts, one was HTML and none of them specified the language for any blocks of code.

Redirecting from the old post URLs

Initially, I had planned on Hugo dealing with redirecting from the old post URL to the new one as Tumblr uses a slightly different URL structure. Because I was using the same domain, this seemed like it should work pretty well, but Hugo does the redirects client-side and I wanted search engines to pick up the change, so I created nginx config.

Tumblr uses a structure like /post/<post-id>/<slug> (with the <slug> being optoinal) where this site uses /posts/<slug> and I decided to only handle any URL starting with /post/<post-id> and do the redirect.

To do this, I used the following one-liner:

jq --raw-output '.posts[] | "rewrite ^\( .url | gsub("https://blog.spike.cx"; "")) /posts/\(.slug) permanent;"' oldblog.json

I use the url field in the post, remove the scheme and domain from it and output an nginx rewrite directive.

So now when a client requests an old post’s URL, they get a 301 permanent redirect to the updated post location. The one-liner results in a series of lines that I pasted into the nginx config:

rewrite ^/post/74130342713 /posts/experiments-with-elixir-and-dynamo-with-otp permanent;
rewrite ^/post/60548255435 /posts/testing-bash-scripts-with-bats permanent;
rewrite ^/post/59389300605 /posts/new-things-learned-from-minecraft-docker-project permanent;

This shows it in action:

$ curl -XGET -I 'https://blog.spike.cx/post/60548255435/'
HTTP/1.1 301 Moved Permanently
Server: nginx/1.10.3 (Ubuntu)
Date: Mon, 26 Feb 2024 05:11:28 GMT
Content-Type: text/html
Content-Length: 194
Location: https://blog.spike.cx/posts/testing-bash-scripts-with-bats/
Connection: keep-alive

My First Programming Project

Last year, my dad was cleaning up and came across my first real programming project. When I was 10 or 11 years old, in sixth grade, my school offered programming classes. The class was taught in BASIC on IBM PCjrs and focused primarily on graphics. This is like 1991-1992.

This is the old school BASIC, where you had to label each line with a line number and we had a dot-matrix printer if we wanted to save our programs. The teacher would hand out special grid paper which accounted for the rectangular pixels that we were working with and it would help out with our assignments. The thing is that this wasn’t even our first real exposure to programming, since the preceeding 2 years, we had computer classes where we wrote LOGO (you know, the turtle that you’d control with a series of commands) and drew pictures on these Atari computers. We never really did much more than RT 90 and PEN UP/PEN DOWN commands, but for my final project, I drew a simplified GameBoy.

Anyway, I loved this class. It was so cool. Our teacher showed us some projects that the 7th and 8th graders had done, and they did some simple animation by clearing the screen and drawing the next frame, so I asked a lot of questions. We had pretty much only learned how to change color, do fills and draw lines and shapes, but the teacher showed me how to write a FOR loop and I kinda understood what it was doing and I had an idea.

Graphics reference with my original diagonal stick, which was too much work.

For my class project, I was going to draw a stick of TNT, animate the sparks on the fuse by cycling through the colors (the colors were indexed 0-15). I don’t know how long I actually spent on it but I swear it felt like a week. And if you had asked me how much code it was, by my recollection, it was like 100 lines of code.

Some printed source code

So this is all the code. I got an A even though it’s only 16 lines. I had to jam in the FOR loop on line 55, so it doesn’t just count by 10s. This concept of numbering one’s lines is so weird and I can’t imagine how it must feel to see this for folks who only got exposed to software in the 2000s.

I’ll transcribe the source here, for posterity (and to show off cool BASIC syntax highlighting):

10 CLS
20 KEY OFF
30 SCREEN 3
40 LINE (90,30)-(55-160),4,BF
50 LINE (70,30)-(70,20),1
55 FOR A= 1 TO 15
70 LINE (79,8)-(71,18),A
80 LINE (74,15)-72,18),A
90 LINE (67,13)-(69,18),A
100 PSET (66,8),A
110 PSET (63,15),A
120 PSET (73,4),A
130 PSET (76,17),A
140 NEXT A
150 GOTO 55

I’d love to find somewhere that I could run this again.

It’s kinda crazy how low resolution this is, which you can tell by the magnitude of the numbers. I had another version that would fill the screen with white to signify an explosion and then end. This one just loops forever, animating the fuse.

The shitty thing is that the year I got this class was the last year they offered programming in middleschool. The following year, the school got new Macs and we were given a typing class instead. For some reason, my town really dumbed down the computer class offerings after that and I wasn’t able to take another programming class until senior year of high school when they offered C++ for the first time, but that’s another story.

After taking this class, I discovered that we had QBASIC on our home DOS computer and I picked up some books at the book store because I was bitten by the programming bug. I do wish I took it more seriously, though, but I did manage to build a simple Pong game. I had an epiphany one night about how to animate a bouncing ball and then it was cake to control a paddle and bounce it around, but I had no score nor did I track when the ball missed.


Older posts