2048 for the PET CBM

CBM PET 2048 This a port of the 2048 game to the CBM PET 4032. This game is part of a work to port 2048 to the C64, VIC20 and 4032. There are not many new games being released for the 4032, which is understandable given that it is an ancient machine which was created as a business machine and not as a gaming console. However, I find it a very challenging task to write games for this very limited platform.

The PET CBM 4032

This year I had the opportunity to acquire an old 8-bit computer from 1980, namely the PET/CBM 4032. This machine is one of the later generations of the PET series of Commodore computers and was mainly intended for the business market.

PET/CBM 4032 - 12" screen.
PET/CBM 4032 – 12″ screen.

There is a reason why I choose to buy a PET 4032 and not one of the older versions, like the PET 2001 or 3000 series. The PET 4032 is one of the first CBM machines that  has a Cathode Ray Tube Controller (CRTC) 6545  chip on board and that has an internal piezo speaker. This means that very primitive video effects are possible with the 4032 and you have the possibility to play some one bit music through the internal speakers.  I also had the opportunity to buy an 8032, which is basically the same machine but has 80 columns of text instead of 80. I did not do this because I think the width of 40 characters is better suited for my purposes and more closely resembles the capabilities of the other 8-bit machines of Commodore. Interestingly, you can convert a 4032 to an 8032 by putting in more RAM, some other ROMS and rewiring some jumpers. They both have the same motherboard.

2048

The game 2048, created by Gabriele Cirulli, is a very popular puzzle game based on 1024 and another game with the name 2048. Although it very much resembles Threes, the author of the game did not know about Threes when he started development on 2048. 2048 is a slide puzzle where you have to pair numbers. Numbers that are paired add up, creating ever increasing numbers of the power of two. The goal is to reach the number 2048.

A 2048 core in C

I always reach for the CC65 tool suite when coding for the 8-bit Commodore range of computers. CC65 is the best tool suite to develop for the 6502 range of CPUs if you ask me. It has a fully functional C compiler with great macro support and a very fine assembler as well. But more importantly, it comes with a super standard library as well. Originally developed by Ullrich von Bassewitz it is now maintained by Oliver Schmidt. The goal of this project was to make a puzzle game that has a machine independent game core. Written in ANSI C89, the game core can easily be ported to other  architectures as well. At this moment I have written a version for the C64 and one for the PET/CBM 4032. In my effort of making the code more or less platform independent, I opted for a solution that provides link time substitution of the screen drawing facility.  In practice, this means that the main code and game core are the same for each platform. The main program then calls hooks at certain code sections to drive the screen. Below are some lines of code from the ‘screen.h’ header file, showing the API used and hooks being called.

(Start rant) A lot of (professional) embedded C code I see when consulting still makes use of preprocessor code substitution for platform independence. If we can do this properly for an old 8 bit machine, we surely can do this better as an industry as well. (End rant)

PETSCII

The CBM PET computers have no graphical screen mode, only a monochrome character mode is supported, giving a display of 40×25 characters. PETSCII, also called CBM ASCII, is a custom character set developed by Commodore, based upon ASCII. There is a character set available with lower and uppercase characters and another one which has only uppercase characters, but contains graphical symbols as well. The latter makes it possible to create some crude graphics. In 2048 I used these graphical characters to create the grid and the numbers on the tiles.

Rendering numbers in PETSCII

There are many ways to use the PETSCII graphical characters to create fancy drawn numbers. I settled upon using some rectangular based shapes to draw the numbers. Using the 10 characters shown below, I used them to create the numbers 0 to 9.

This results in numbers that are 3 characters wide and 5 characters high, as shown below. The screen width of the 4032 is limited to 40 characters, this means we have 10 characters to our disposal to draw a tile, including the grid. The number itself can only be 9 characters wide, so we can also draw a grid. That would limit the amount of digits per tile to 3, too little for representing the number 2048.

The numbers 0 through 9, drawn using the graphical characters.
The numbers 0 through 9, drawn using the graphical characters.

Luckily, we can condense the numbers, eliminating the space between them. For doing this, I wrote a routine that merges numbers and glues them next to each other. For doing this, I introduced a data structure where each of the 10 graphical characters is mapped to a binary representation of 4 bits. The 4 bits stand for top, bottom, left and right. If you look at the used characters, they each can touch the top, bottom, right and left side of the space they use. You can look at them as little tubes that have exit points at the different sides of the rectangle they occupy. Merging them is now a simple operation of a bitwise ‘OR’ function.

Merging PETSCII characters.
Merging PETSCII characters.

As an example let us connect the vertical bar ‘|’ and ‘T’ shaped character. The ‘|’ has exit points at the top and bottom, giving bit pattern ‘1100’. The ‘T’ has exit points left, right and bottom, giving bit pattern ‘0111’. A bitwise ‘OR’ between both bit patterns gives back pattern ‘1111’. If we look at the table, this results as the ‘+’ sign.

The number 8192, printed out in condensed format.
The number 8192, printed out in condensed format.

The same technique of merging is also used to draw the grid. I wrote a horizontal and vertical line routine that does not overwrite the underlying lines, but merges them, giving nice crosses at the intersections. Here’s the code that shows the heart of the merge routine. The variable s points to a location on screen, i.e. the existing situation. The variable ‘data’ points to the new character to be merged with the existing one. The routine ‘char_to_code‘ returns the bit pattern as described above for the given character. The routine ‘code_to_char‘ does the opposite, returning the character that corresponds with this bit pattern. When ‘char_to_code‘ encounters a character it does not understand, it will return a value with bit 7 set to one, in that case we do not merge, but just return the given character in ‘data‘.

This merging comes at a computing cost, so for the game I draw the condensed numbers 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 and 2048 in an offscreen buffer and use them as tiles during game play.

2048 for the 4032

At the moment I’m writing this blog post I have version ready for the C64 and CBM PET 4032. The code is available on github, so you can a look on how it is all made. A compiled version is available as well. You do not need a real CBM PET 4032 to test it if you want. An excellent option is to use the VICE emulator xpet for this.

Download 2048.
You can download the game here.

Below is a movie of the game in action on a real PET 4032… enjoy the green.

Leave a Reply

Your email address will not be published. Required fields are marked *