Back to 1985: How We Remade ChipWits for the C64

In September 2023, the ChipWits team discovered a stack of Commodore 64 disks containing the original FORTH source code for ChipWits, a game first released on the C64 in 1985. In their ChipWits Blog Post, you can read more about this discovery.

About a year later, I came across a discussion on Slashdot, which inspired me to reconstruct the complete build process. I wanted to honor Mike and Doug, the original creators, by making their work truly accessible to everyone again.

It took longer than expected — Doug once joked, “It always takes longer than you think” — but eventually I produced a set of build instructions that generate a nearly (almost byte-for-byte) identical program to the original ChipWits release. In the rest of this story, you’ll read about my process and the surprises I encountered along the way.

Where to Start?

I had 21 “virtual” disks right in front of me.

Photo of the 21 disks

My first thought was: “Where on earth do I begin?” Randomly choosing a SuperForth environment and compiling all the source files was not the way to go — who’s to say that would produce the same game as back in 1985?

To make a true one-to-one comparison with the original release, I had to take a step back and not rush into compiling. I temporarily set the disks aside and spent over two weeks immersing myself in Forth, specifically SuperForth 64. I read the SuperForth manual so many times that I almost memorized it. That knowledge proved crucial to understanding how the game was originally built.

How a Forth Program is Structured

My goal was to produce a build that yields exactly the same bytes as the original release. But how do you verify that with a Forth program?

Forth organizes functions into so-called WORDS, similar to functions in other languages. When defining a WORD, you can only call other WORDS that have already been defined. For example:

: A <functionality of A> ;
: B <functionality of B> ;
: C A B ;

We can think of each WORD as a small piece of code:

Schematic drawing of a WORD

All these WORDS are in a linked list, with the most recently defined WORD pointing to NULL:

Illustration of a Forth word list

It’s interesting that the Forth compiler/interpreter itself is largely written in Forth, with only a small assembly part for the specific CPU. That made Forth famous for its ease of porting to other systems —and it is also easier to understand.

If you look at the memory layout of a Forth program, you see recognizable patterns for the WORDS in RAM:

Memory layout of a SuperForth program, the yellow marked text are the Name fields of the WORDs

For my analysis, these patterns were extremely important because they allowed me to compare my new build with the original ChipWits version. Any differences in these patterns pointed directly to where I still needed to puzzle things out or investigate further.

Back to the Disks

Armed with this knowledge, I picked up the virtual disks again. But first, I examined a disk that wasn’t part of the “repro” set: the official release of ChipWits. That disk contained a file named CW.GM, which held the final compiled version of the game.

Notes from the found archive indicated that some of the new disks also contained a version of ChipWits. On one of them, CW Boot.d64, I found a file named GAME. It immediately struck me that GAME had the same file size as CW.GM, so I decided to compare the two.

Byte for byte compare between the files GAME and CW.GM

Indeed, the files were very similar. The main differences were because, in CW.GM, the Name fields of WORDS had been overwritten with spaces. You can recognize this as the result of the Forth command APPLICATION (see the SuperForth 64 manual). When I applied the same command to GAME, almost all differences disappeared. In other words: if I could exactly rebuild GAME (with all original WORD names intact), then I had effectively reconstructed CW.GM entirely. I therefore focused on GAME, using CW.GM only as a reference.

Locating SuperForth 64 Version 2.1

By inspecting the hex dump of GAME, I discovered that the original ChipWits release was built with SuperForth 64 version 2.1.

Greeting message of SuperForth inside the file GAME

At first, I thought a copy of SuperForth 64 v2.1 would be easy to find online, but after countless searches, I only found older or newer versions. I asked around in the Dutch Forth users group, but nobody seemed to have 2.1 lying around.

Just when I was about to give up, I realized that CW Boot.d64 might hold something useful besides GAME. And sure enough, it contained several files that, when loaded, displayed a SuperForth 2.1 splash screen. After thorough investigation, I discovered that CWMIN was exactly what I needed: a minimalist version of SuperForth 2.1 with only the system’s core WORDS. This was a breakthrough, because it allowed me to create the same runtime environment the original developers had.

Finding the Right WORDS

I could have started randomly compiling, but there was a better method. From GAME, we could deduce exactly in which order the WORDS were defined. I wrote a small Python script to export the WORD list from GAME to text, so I knew precisely the compilation order the original developers had used.

I then matched those WORDS to the source files spread across the various disks. This produced a mapping like so:

Mapping words to SCREENS (c64/forth/Game Screens.forth in the chipwits-forth repro)

This revealed which SCREENS (Forth source code blocks) belonged to which disk and the order in which they needed to be loaded. For example:

  • Forth Source Screens.d64
    • Use LOAD SCREENS 1 and 2
  • CW Joy+Menu Screen.d64
    • Use LOAD SCREEN 1
  • CW Game Screens.d64
    • Load the screens in this specific order:
      • 172 182 THRU
      • 255 LOAD
      • 183 195 THRU
      • 246 254 THRU
      • 256 265 THRU
      • 330 338 THRU
      • 266 275 THRU
      • 320 329 THRU
      • 276 290 THRU
      • 196 208 THRU
      • 313 319 THRU
      • 311 312 THRU
      • 291 307 THRU
      • 209 240 THRU
      • 308 310 THRU
      • 241 245 THRU

With that plan in hand, I could finally begin in earnest.

“Okay, Let’s Build!”

With confidence, I started SuperForth 2.1 using CWMIN and began compiling. The first two disks compiled fine until the compiler stumbled on the line:

G.M.I ( CHAR.COPY)

The machine froze completely. After a brief investigation, I discovered that G.M.I was not needed during compilation — it only matters at runtime when the game actually runs. I commented out that line and started again. This time, all the SCREENS compiled in the correct order without problems. The final build had exactly the same size as the original CW.GM and GAME files.

Is It Really the Same Build?

Matching file size and structure was promising. But are the files truly identical in content? To test this, I performed a byte-for-byte comparison between the new build and the original. There were still a few differences, but these were mostly due to:

  • Uninitialized memory (via ALLOT or similar Forth commands) leaving random residual bytes behind. These have no functional impact as they are later overwritten or ignored.
  • In some cases, memory is reserved and initialized in a slightly different order, because we now boot from a minimalist SuperForth system.

These minor differences are not functionally significant and can be ignored. However, there was one thing that couldn’t be overlooked: in the compiled 6502 assembly for the WORD COLD, a patch was applied. At location 0x1890 instruction LDA has been replaced by a JMP (part of the machine code is skipped)

At location 0x1890 instruction LDA has been replaced by a JMP (code is skipped)

It appears that this patch was manually applied at one time to work around a small glitch. Without this fix, starting CW.GM produces a graphical error—the jump skips code that normally clears the screen and prints the SuperForth welcome message. This modification does not really influence the functionality of the game so for now we leave it as is.

With this one exception, the new build behaves exactly like the original, and all other differences are due to uninitialized bytes or minor changes in the way Forth is built. The resulting build instructions can be found here.

Next Steps

It’s exciting to see how close we are to a fully authentic rebuild of ChipWits. There’s still plenty to do, such as investigating sprite data, character sets, and any historical notes in the source code that explain that one patch in COLD.

We will continue gathering details, tying up loose ends, and checking every piece of code until the game matches the original down to the last byte. If you, like me, get excited about digital archaeology, stay tuned — more updates will follow!

Ready to Get Started?

I hope you enjoyed reading about my journey of discovery. Even better, try it out for yourself! All the information and files are available online:

That’s the story so far. We hope this glimpse into bringing ChipWits back on the C64 inspires others to embark on retrocomputing adventures! If you have any questions, feedback, or additional resources about SuperForth 64, join our Discord. Happy hacking!

Oh hi there đź‘‹
It’s nice to meet you.

Join Our Mailing List to Stay Notified About ChipWits!

We don't spam!

Are you interested in learning more about ChipWits and tracking our development? You can unsubscribe at any time. We generally send a short email about the game once every week or two. Read our privacy policy for more info.

Leave a Reply

Discover more from ChipWits Robot Coding Game

Subscribe now to keep reading and get access to the full archive.

Continue reading