July 24, 2026

101 BASIC Computer Games for Ben Eater’s 6502

TL;DR; or “Just Get to the Programs!”

For reasons that you can read in the rest of this post, I was inspired to port the programs listed in David Ahl’s now-classic, 1973, book “101 BASIC Computer Games” so they could be directly run on Ben Eater’s 6502 breadboard computer using his (or my) builds of Microsoft BASIC.

This project was wholly enabled by Maury Markowitz’s wonderful work of preservation in converting the original printed listings to files. Without that, I’d have had to type all of these listings in myself, or do something similar to Maury’s OCR/AI conversion process.

So … if you have built your Ben Eater 6502, and gotten MS-BASIC running on it, and just want to get to the programs and start running them you’ll find them on my GitHub.

The repository has an overview and an explanation of how to load/run the files, compare them to the original, un-ported versions, and companion files that describe what was needed to make each program run.

From the Top – Porting “101 BASIC Computer Games” …

After recently building Ben Eater’s 6502 breadboard computer, and getting “WozMon” and Microsoft BASIC running on it, I was intrigued to explore whatever software I could find from the time when these sort of machines were just becoming available (this would be in the 1970s).

Where to find such software?

There are lots of possibilities here, some of which would be much more involved to make run on this particular computer than others. My first 6502 build only has serial I/O, so whatever I was going to run had to be workable via a simple terminal.

Since Ben already had Microsoft BASIC running, that seemed like a reasonable place to start …

101 BASIC Computer Games

Many retro-computing enthusiasts, especially those that grew up with these kinds of machines, are familiar with David Ahl’s now-classic, 1973, book “101 BASIC Computer Games”. It contained listings, in BASIC, for 101 programs (most are games, not all), that you could type into your computer and run for yourself.

If you transcribed things accurately, they worked; if not, issues could arise – some obvious, some very subtle.

Also, since dialects of BASIC had, sometimes significant, differences, you often had to make adjustments to the code for it to work on your particular computer or version of BASIC (called “porting“). This was both a source of valuable education and, sometimes, frustration and, either way, it was an intrinsic part of the experience.

From Printed Listings to Files

Now, I did not particularly fancy typing in these listings myself. Back in my childhood it was something I did a lot, as even through the mid 1980s computer magazines still carried type-in-listings. But today, well, I’d rather focus on the code itself.

What to do?

Fortunately, this was answered rather neatly when I came across Maury Markowitz’s wonderful work of preservation, in which all of the upfront, hard, work in getting the printed listings into actual files had already been done! Maury also describes the process, its pitfalls, and more and that is well worth reading.

It is no exaggeration to say that without Maury’s work, I wouldn’t have even attempted this.

The Goal vs. Reality

Ultimately the goal of this project is to port all 101 programs (as they’re not all actually games) from the book so they can just be loaded and run, as faithfully as possible, by anyone that has built Ben’s 6502 and gotten MS-BASIC running on it.

No need to code, or change, anything … just load and go …

There is a “sub-goal”, also, which is to make the minimum changes feasible to preserve as much of the original code as possible, but sometimes more substantive changes are required.

As of this posting, I’m about 1/3 of the way through the full 101 programs, with some quite interesting ones in that mix.

There is no specific methodology to choosing which program to tackle when. I started off choosing some I thought looked interesting, and have picked-and-chosen since then on a similar basis but also considering how much time I had for that session and how involved the porting for a given program looked.

Most of those tackled so have been relatively straightforward, though I have already come across a handful that it is clear are going to be quite difficult to port and, indeed, a few that will likely need extensions to MS-BASIC to make feasible1.

So, we may not wind up at the full 101 … but if it is in my repository, it will load and run directly.

Porting – What is it, and what is involved?

These listings pre-date MS-BASIC by several years. Even though MS-BASIC was fashioned after DEC’s “BASIC-PLUS”, a dialect for which a number of these programs were written, there are still differences; big enough differences, in fact, that the code often either uses unsupported commands, isn’t syntactically valid for MS-BASIC, or it is but it doesn’t function as intended.

At the simplest level, some of the programs do run as-is (and are marked as such) – but it’s not that many and for any that don’t they have to be “ported” to our target version of MS-BASIC. That’s the fancy way of saying “convert code for this system/language to this other system/language”.

How involved that is depends on a) what differences exist between the dialect of BASIC the code was originally written for and our target version of MS-BASIC and b) to what extent those differences manifest in a given program.

Porting is complicated by the fact that BASIC is generally an interpreted language. That means each line of code is processed as it is reached, in many cases from its raw text expression2. If a line of code is never reached, it won’t be parsed or executed; and since that’s where syntax errors and missing commands etc. get reported, you have to test fairly extensively to ensure all the lines of code are being executed.

An additional, though usually minor, complication is that in some, though surprisingly few, cases the file-based copies of the code from Maury’s project are not 100% accurate transcriptions. Fixing this means going back to scans of the printed book to find the differences and, in some cases, the print is not very legible making it a bit of a challenge!

With all that in mind, here are some of the more common types of things I’ve encountered/done in porting these programs:

Trivial Syntax Changes

This is the most basic level of “porting”, and they’re usually easily caught as they will throw errors when encountered.

Perhaps the most common example is changing simply statement separators from \ to : for multi-statement lines. Another would be RND referenced as a value rather than as a function: RND().

Syntactically Valid Functional Differences

Some functions and statements look the same in different dialects of BASIC, but do not necessarily behave the same way. This can lead to very subtle issues.

The commonly encountered construct: RND(0) is legal in our version of MS-BASIC. However, unlike it the original BASIC dialects that many of these programs use, it’s behavior or function is different. In MS-BASIC it does result in an appropriate raw value, however that value will NOT change throughout the execution of the program! Other dialects produce a different number every time RND(0) is called.

For MS-BASIC you have to call RND() with a value greater than 0 (nominally RND(1)) if you want different values on every call.

Without this change, random things are not random at all and this results in either things going exactly the same way every turn/run or just not working at all … neither of which is conducive to playing games.

There are other examples of this sort of thing called out in the notes accompanying each of the ported programs.

Unsupported Keywords

It is worth bearing in mind that in 1973, when the book was first published, most of the machines running BASIC were mini-computers and had substantially better capabilities than anything a hobbyist was likely to be running at home.

As such, their versions of BASIC were often more elaborate than early MS-BASIC, and included potentially many keywords and functions that MS-BASIC did not.

These are, fortunately, easy to find as they will cause errors, and stop the program, when encountered.

Addressing these missing keywords is often tricky.

In simple cases they may not be necessary. The RANDOMIZE keyword, for example, is not supported by MS-BASIC, but it is also not required, and can simply be removed.

More often, however, it is necessary to either come up with a manual implementation of the missing functionality or, perhaps, change the code to work in a different manner3. Two recurrent examples of this are the READC and CHANGE keywords.

The CHANGE function4 turns a character string into a numeric array of ASC-II values, who’s zeroth index is the number of characters in the the string, and indexes 1 through length are the the character values. Which can be simulated like this:

Original Code
Recreation of CHANGE Functionality

Not all unsupported keywords or functions can be replaced or simulated in this manner. Some, such as TAB(), which is present in MS-BASIC but works differently, require access to the current output cursor position to function. Short of re-writing ALL of the code that PRINTs to the terminal as well, the only way to fix such issues is within the MS-BASIC assembly code itself.

Bugs

These come in different forms, and can be the trickiest issues to fix.

Some are simply logic issues in the original code; fixing those requires first understanding what the original behavior SHOULD have been. But there is also the question of whether to fix those types of bugs at all.

My approach there has been to only fix those that prevent the program from running at all; those that just leave quirks or oddities in the game or that just deviate from the description but are a product of the original code (regardless of porting), I’ve left alone.

Others result from very subtle differences in the behavior of the original dialect of BASIC the code was written in vs. the same construct in MS-BASIC. These are, perhaps, the hardest problems to deal with, partly because they can just be difficult to find.

For example, also in bagels.bas, the code has a routine (starting on line 150) that is supposed to generate three unique digits (there’s more detail in my notes on the specific game). For it to work as-written, FOR/NEXT loops on its dialect of BASIC would work such that the loop body only runs if the TO condition isn’t met. Most BASIC implementations don’t work this way, and execute their loop at least once, and MS-BASIC is definitely one of those.

No error is produced in this case, the code simply looks like it is running but then enters an infinite loop. There’s no debugger available, so a series of PRINT statements was used to track down the issue. Figuring out a fix wasn’t hard, but it did take a bit of work to figure out why the code simply looped continuously!

Learnings

It has been decades since I wrote any BASIC code (I started my programming journey with Z80 assembly language); other than occasional VBA functions in Excel (at least until Python support was added), it was back when Visual Basic 6 was “current” (and popular, so almost 30 years ago).

Coming back to it was trivial; it’s not a hard language to learn nor pick-up again.

In doing so, however, with such old versions of it, there have been a good number of things I’ve learned about both Microsoft BASIC as it was in the mid-1970s and the versions of BASIC that inspired it/it was derived from. In part, this is because I’ve not found a proper reference manual for Microsoft BASIC, so some experimentation has been required (and when that fails, “cheating” and looking at the source 6502 assembly code).

These include things like “Oh, I didn’t realize MS-BASIC supports XYZ” (multi-statement lines, ON GOTO, implicit DIMensioning and things of that ilk).

I’ve been documenting those aspects in the repository as I’m doing the porting work.

Back to Work

On that note, I am going to wrap this up and go back to porting more programs. I’ll post an update if I either finish that work or if I get to a point where I’ve done as much as I can and any remaining programs are infeasible to port!

  1. Some behaviors/commands in the source programs/BASIC dialects need access to low-level machine state to emulate or write an alternate way of handling, and that can only be done within the BASIC implementation itself. ↩︎
  2. Tokenizing and compiled versions of BASIC avoid this concern, as lines of code are either evaluated as they are entered, or when they are compiled, so you don’t risk missing the validation of any lines of code. ↩︎
  3. Generally I prefer the former, as the intent here is to make changes as minimal as is achievable in oder to retain as much fidelity to the original work as possible. ↩︎
  4. Refer to the original source dialect’s BASIC reference manual. ↩︎