Mimsy Were the Borogoves

Hacks: Articles about programming in Python, Perl, Swift, BASIC, and whatever else I happen to feel like hacking at.

42 Astoundingly Useful Scripts and Automations for the Macintosh

Work faster and more reliably. Add actions to the services menu and the menu bar, create drag-and-drop apps to make your Macintosh play music, roll dice, and talk. Create ASCII art from photos. There’s a script for that in 42 Astounding Scripts for the Macintosh.

TRS-80 Color Computer Programming Tools

Jerry Stratton, May 9, 2020

Hello, World color bars

The TRS-80 Color Computer is a fascinating old-school personal computer. It is based off of the Motorola 6809 chip, and was the second computer I owned.

Most of this is about Extended Color BASIC on the CoCo, which I didn’t use much back in the day except for typing in programs from Rainbow. Most of the work I did for myself, I did in Microware’s OS-9.

If you want to write BASIC programs for the CoCo but prefer more modern methods, consider superBASIC. It provides loops, longer variables, and more, to make your CoCo code easier to understand and modify.

If you want to type in old code from Rainbow, look at rcheck+. It implements Rainbow’s rcheck+ algorithm in Perl.

Both of these allow you to more easily create CoCo code on a modern computer.

May 12, 2021: BASIC tokenization examined

If you’re in the habit of transferring BASIC files from old computers to modern ones, you might discover strange characters in the files. They’re like a strange combination of text and binary. This is not a compiled program, however. In old-school BASIC, there was a difference between compilation and tokenization.

Compilation converted BASIC code to machine code, and compiled files would usually be stored with a file extension indicating that the code should be run directly rather than interpreted. Often, this extension was some variation of “.BIN”. On personal computers at least, compilation usually required third-party software to convert the BASIC statements to machine code.

Compiled programs were no longer BASIC. They were machine code. They couldn’t be listed or edited, at least in BASIC. It generally wasn’t possible to convert a compiled BASIC program back to the original BASIC. Like any other compiled software, if you wanted to recompile it you needed to keep the source code on hand.

The default BASIC on these personal computers were also not saved as straight ASCII. While saving to text was usually an option, the default for most BASICs was to tokenize programs both in memory and on disk. Tokenized files were usually saved with some variation of a .BAS file extension—often the very same extension used for straight ASCII, non-tokenized files. Whether a file was tokenized or non-tokenized was a bit in the directory listing for that file, not in the file itself.

Unlike compiling a program, which translates code statements and functions into machine language, a tokenized BASIC program is still BASIC. In the computers I used, tokenization was mostly, if not completely, a one-to-one translation of BASIC statement/function to the one- or two-byte token for that statement or function. This saved space on the system. Both disk space and RAM were limited on older personal computers. But it also made it much easier for the system to run the code on the fly—interpret it—and made the interpretation much faster.

Without tokenization, the difference between RESET and RESTORE in the Radio Shack Color Computer’s Extended Color BASIC, for example, won’t show up until comparing the fourth character. With tokenization, the difference shows up on comparing the first character—9D is the tokenization for RESET and 8F is the tokenization for RESTORE. Nor is there any reason to scan for the end of the statement or function. Each statement or function is at most two bytes.

April 7, 2021: What are the 8 bits in 8-bit computing?
AND and OR on the Color Computer

Why? Where do these results come from?

On the Facebook CoCo group, someone recently asked about how I handled bit-checking in a question I asked on the Retrocomputing StackExchange about the joystick. They didn’t phrase it as a question about bits because they didn’t know that their question was about bits.

It’s not surprising. I don’t know about other computers, but Radio Shack tended to hide the bitwise nature of their 8-bit computers. The only BASIC functions that worked with bits were the logical operators AND, OR, and NOT1, and they weren’t explained as bitwise. The first two are given a page in Getting Started with Extended Color BASIC, page 78, where they’re explained as if they’re the English words AND and OR.2

But these operators do not behave as the English words do, or as the explanation implies they do. Here’s an example. Go into your CoCo or an emulator such as Xroar, and type:

  • PRINT 3 AND 5
  • PRINT 3 OR 5

The first should give you 1 and the second should give you 7. In most modern programming languages, both would give you true, which, depending on the language, might be a boolean value or it might be the integer 1. It might even be one of the two values, the 3 or the 5, because of short-circuit evaluation.

How does Extended Color BASIC arrive by its return values? The answer is that AND and OR are bitwise operations. These are 8-bit computers. They describe their numbers in 8 bits3. Here are the bits for the numbers 3 and 5:

byte value8 bits
300000011
500000101

The logical operators do not compare bytes. They compare individual bits at matching bit locations. What AND does is, if the bit in the same location in each byte is 1, the bit in the resulting byte is 1. If either of the two bits are zero, the bit in the result for that location is zero. What OR does is return 1 if either of the bits are 1, and zero only if both bits are zero. So here’s what AND and OR do when comparing 3 and 5:

February 13, 2021: Color Computer binaries from decimal values
Space Hawk

At the end of my post on the first version of cocobin, I wrote:

It’s also likely that some binaries were provided as decimal instead of hexadecimal numbers.

And only a few weeks later, here I am. I found a really nice Galaxian/Space Invaders-style game by Rodger Smith in the February 1985 Hot CoCo.1

He used decimal numbers for his DATA statements, so I added that feature to cocobin. If a file or BASIC program contains decimal rather than hexadecimal numbers, add the option --decimal to the cocobin command line.

Also as expected, adding this feature also highlighted another common custom of the era: the DATA items often included a marker to denote the end of the data. Most commonly, as I recall, this was the word “END”, or (for machine code) a negative 1. Smith used the number 999. So I’ve added the ability to recognize “END”, “999”, or “-1” at the end of a line of DATA in a BASIC program. If the program sees any of those key words at the end of a DATA line, it assumes that that is the end of the data to be read.

Either of those keywords not at the end of a DATA line will still be seen as an error, since none of them represent valid POKEable numbers.

The script now accepts the following arguments:

load addressdecimal or hex address for location of binary data in CoCo RAM
exec addressdecimal or hex address for starting execution; defaults to load address
filenamesfile[s] to pull data from; data can also be piped
--basicthe text is a BASIC file; pull hex values from DATA lines
--columns <column count>verify that each line contains a specific column count
--decimalthe numbers are decimal numbers, not hexadecimal
--helpprint this text
--quietdo not output bin data
--verboseprovide information about the binary program

Also, while this is not a change, I did finally verify that the script works when used with multiple files. Charles Husak’s “The Little Runner” from the March 1984 Rainbow uses three BASIC programs to POKE the binary into memory. This command line worked to create a working binary from those three files:

  • cocobin --basic 13000 RUNNER*.BAS > RUNNER.BIN

Interesting little game!

February 10, 2021: Read BASIC out loud

In my continuing quest to make it easier to successfully type programs from books and magazines, I had the great idea of having my Macintosh read the code out loud, freeing me to look solely at the original text while verifying the code. This is useful not just for finding errors that rcheck+ says must exist but also errors in code that doesn’t have checksums such as the one- and two-liners in The Rainbow.

The readBASIC script (Zip file, 3.6 KB) is especially useful for the 1984 run of The Rainbow, which uses an rcheck that simply adds up memory used instead of performing a rudimentary checksum, and Hot CoCo, which has no validation at all unless you count the 32-character lines. I recently acquired several issues of Hot CoCo and I pretty much run readBASIC on all of the programs I type in from that magazine. Whether an error shows up on testing the program or not, I almost certainly mistyped something on any program of any reasonable length. Those bugs are likely to trigger when I least need them.

It turns out I’m not the only person to think of having the computer read code back to you. In the October 1987 issue of The Rainbow, there’s an article by Bob Roberts that does the same thing. Of course, his is more complicated since it has to fit in memory around the BASIC program it’s reading. It doesn’t read the files (although, technically, there’s no reason it couldn’t) but rather reads the actual BASIC program from RAM. Nor is it a machine language program invoked with a special keystroke, like the rcheck+ program. Instead, it’s literally a BASIC program running above the real BASIC program, starting at line number 60000.

Of course, a BASIC program on an eighties computer required special hardware to generate speech. Roberts’s required Radio Shack’s Speech/Sound cartridge. Modern computers have speech built in. You can play around with it on the Macintosh command line using the say command. I go over this command in more detail—how to use the voices of various languages and accents—in the Diversion About History section of 42 Astoundingly Useful Scripts and Automations for the Macintosh.

My first attempt at having the iMac read BASIC code out loud was simply to send each line of BASIC to the say command. Given the lack of spaces in most old-school code, you won’t be surprised to learn that this did not work well.

December 30, 2020: Create Color Computer binaries from hex values

The December 1987 issue of Rainbow has a very interesting program from John Mosley that purports to be “a four-voice music and graphics program” that works with the CoCo 1 and 2. It consists of a short BASIC program to create the graphics, and a shorter BASIC program to allow the reader to type in the hexadecimal values for the music, one value at a time.

Screw up one number, and you have to start over, this time not screwing up elsewhere. Or you have to understand POKEing enough to rePOKE just the numbers you screwed up, and know where they are—probably by writing a BASIC program to display values in memory and ask you if they’re correct, one by one.

It seemed more reasonable to type all of the hexadecimal numbers into a text file, and then use a script to create the BIN file; if there’s an error, fix only that error in the text file instead of retyping everything.

The format of BIN files turns out to be fairly simple. From Walter Zydhek’s Disk BASIC Unravelled II, there is a preamble and a postamble, both five bytes long. The preamble contains the length of the data and the address the data should be loaded to:

ByteValuePurpose
000Preamble flag
1-2XXXXLength of data block
3-4XXXXLoad address

The postamble contains the execution (EXEC) address:

ByteValuePurpose
0FFPostamble flag
1-20000Dummy value
3-4XXXXExecution address

The script accepts the following arguments:

load addressdecimal or hex address for location of binary data in CoCo RAM
exec addressdecimal or hex address for starting execution; defaults to load address
filenamesfile[s] to pull data from; data can also be piped
--basicthe text is a BASIC file; pull hex values from DATA lines
--columns <column count>verify that each line contains a specific column count
--helpprint this text
--quietdo not output bin data
--verboseprovide information about the binary program
November 11, 2020: New, improved rcheck+ for Rainbow Magazine code
ON L GOSUB

This, from Le Lutin in the July 1987 Rainbow, was a very annoying and time-consuming error to debug just using rcheck. It was obvious once brought into Xroar.

I’ve added a few new features to the rcheck script to make it more useful for typing in code from The Rainbow.

--debugprovide a hexdump of the tokenized BASIC file
--rcheckuse the original rcheck rather than rcheck+
--shift <x>shift all checksums by x
--verboseshow checksums for all lines
[xxx]show checksum for line xxx
[xxx:yyy]verify line xxx against expected checksum yyy
[:yyy]verify checksum yyy at the end of the code

rcheck+ for macOS (Zip file, 2.5 KB)

The big, important change is that you can now specify the expected checksums on the command line. You can continue to use rcheck as before, and its behavior will not change. But if you add “:yyy” to a line number, it uses “yyy” as the expected checksum. For the final line, you can use simply “:yyy” or “yyy”.

  • ~/bin/rcheck MEMOCARD.BAS 130:15 210:170 320:9 :167
  • 130: 15
  • 210: 152 238 (-18); possibly a 4 where there should be an F?
  • 320: 247 238 (-18)
  • END: 149 238 (-18)

When a checksum does not match the expected checksum, the script shows the difference. This is extremely helpful, because often merely knowing that the checksum is off by, say, 32, tells you what the likely problem is—a missing or extra space, or an incorrectly-cased letter. In fact, some errors are common enough that I’ve put a check for them in the script, as you can see in the example.

  • The dash is right next to the equals on my keyboard, so that’s a common mistake.
  • I’ve no idea why I often type 4 where I should type F, but I do.
  • Ditto with typing a dash instead of an equals sign.
  • Also, very commonly spaces will not be obvious and so will not be typed when they appear in a remark, especially when they appear (I suspect) at the end of a remark.
  • Multiples of 32 can be the result of case issues, since the difference between upper and lower case characters is 32 in ASCII, or multiple missing/extra spaces.
  • Every once in a while, not only can’t I find the supposed error, but the very next block of code is also off—by the inverse of the amount the previous block was off. I suspect that these are typos in the Rainbow checksum block.
August 12, 2020: Hunt the Wumpus: Conditional code and include files in SuperBASIC
I smell a Wumpus

Uh oh… never bump a wumpus.

I never played Hunt the Wumpus back in the day. I bought my computer in the summer of 1980, and by then the game had become legendary both in its fame and in its obscurity. I never saw a copy of 101 BASIC Computer Games nor did I have access to the college computer networks that were its lair. So when I saw a version of it in the Best of Creative Computing Volume 1, I decided to type it in and see how it works.

It’s clearly designed for what would have been considered a wide output format a few years later. The longest string that gets printed is 56 characters long, “BOTTOMLESS PITS - TWO ROOMS HAVE BOTTOMLESS PITS IN THEM”, from the instructions.

That string, surprisingly, would have fit just fine on my first computer, a TRS-80 Model 1. The Model 1 had 64-characters per line. But most home computers used an unmodified television for output. That many characters per line would have been unreadable on those computers, so they had widths usually ranging from 32 to 401 characters per line.

Coming about two years before the first mass market home computer, this program was probably meant for university computers, and may well have used a teletype or printer for its output. Such output devices usually had 80 characters per line, but common printers did exist with 64 characters per line, and of course room was needed for margins. If you assume ten character margins, that leaves 60 characters for output, which comes very close to the 56 character maximum.

Also interesting: the listing was meant for much younger eyes than mine. The 227 lines of code are all on one page. You can see it on page 250 of the book at the Internet Archive.

Like most programs of its era, following the logic is like following a strand of spaghetti, although it’s not nearly the mass of text that programs like it would become when memory became limited.

So of course, after verifying that it worked in PC-BASIC, I decided to convert it to SuperBASIC and create a version that I could play on the Color Computer (Zip file, 12.0 KB).

July 8, 2020: Reversi in SuperBASIC on the Color Computer

Reversi is a fun game to write on an early computer. I suspect one of the reasons it was so popular in early BASIC books is because it’s also an easy game to write on early computers. It’s very easy to get a version that basically works, even if it doesn’t work well.

I took the logic for this game from Tim Hartnell’s Giant Book of Computer Games. It was a fun game, but it didn’t handle everything it really ought to have. That was Hartnell’s style: provide a basic structure, and let the reader learn by adding to it. Among the things that needed to be added were:

  • Require a move by the human player if one is available.
  • Recognize more quickly that the game is over when the game is over1.
  • Disallow a move by the human player that doesn’t flip any pieces.
  • Recognize that the game is over if one player has no pieces. Sadly, I have lost all of my pieces while playing this not particularly smart game. My excuse is that I was often playing the game while distracted by programming the game.

And of course there were a lot of other changes I wanted to make so that the game would play better on the Color Computer.

Reversi checking moves

Checking to see if the player has any valid moves, and highlighting them as they’re found.

I decided it would be even easier to learn by adding to it, if I first rewrote it completely in superBASIC to make the logic easier to understand. As written, the game uses all of the block types currently possible in superBASIC: loops, switches, and both if/endif and if/else/endif. It’s a very good example of how to use superBASIC to write an old-school BASIC program.

While my next game project is going to use the Color Computer’s graphics screen, I decided to keep this one retro. The board is constructed using text, just as in Hartnell’s version, with ‘O’ for the human player and ‘X’ for the computer. This makes it easier to manipulate the board; for example, highlighting a move is as simple as adding 32 to the ASCII code for the character. The characters themselves are stored as numbers, making that sort of conversion even easier.

The computer’s tactics are pretty basic. It uses a few decent metrics to decide on what a good move is. These are in the findMove subroutine:

June 10, 2020: Convert PCBASIC code to TRS-80 Extended Color BASIC
Tim Hartnell’s Reversi

One of the nice things about the older strategy games is that it’s easier to win…

I recently found Tim Hartnell’s really nice Giant Book of Computer Games. Hartnell strikes exactly the tone I was looking for with 42 Astounding Scripts. Breezy, informative, and filled with useful code.

While he writes his book for “Microsoft BASIC on an IBM PC” he specifically avoids anything that might make it unusable on other computers, “no PEEKs and POKEs, no use of graphic character sets, and no use of such commands as SOUND or PLAY. I’ve assumed you have access to READ and DATA, and that your screen is around 32 to 40 characters wide”.

This makes it very suitable for customizing for any of the old 8-bit computers such as the TRS-80 Color Computer line. The changes that need to be made to get these programs to run on the CoCo are somewhat rote, and mostly easily automated. So of course I wrote a script for that (Zip file, 6.1 KB).

  1. On the IBM PC, PRINT TAB started from 1, and printed at that character. In Extended Color BASIC, PRINT TAB starts from 0, and moves that many characters over. So the script reduces PRINT TABs by one. This is especially important for board games like reversi. You can also use --shift-tabs xx to further shift any PRINT TAB statement to the left. For example, Hartnell’s chess program prints at tab 9, which pushes the chess board just barely over the edge of the 32-character CoCo screen.
  2. The IBM PC uses a bare RND function to generate a random number between 0 and 1. Extended Color BASIC uses RND(0) for the same. Most of the time, Hartnell uses RND to generate an integer, by multiplying the real number by a whole number and taking the INT of that. The format and variations are complex enough that I chose not to try and convert that to ECB’s cleaner RND(x) function. Hartnell’s random numbers usually start at zero, whereas the RND(x) function starts at 1.

Since the Color Computer’s screen is 32 characters wide, I chose to make an attempt to reformat PRINT statements to 32 characters maximum. It works surprisingly (to me, at least) well. The script handles these in two different ways. For PRINT statements that are each on their own line, it collects the statements and then recreates them in a series of single-digit incremented lines. If they’re followed by an INPUT statement, the string from the INPUT statement is also merged into the PRINT statements.

May 30, 2020: A manual for superBASIC

Because I like printed manuals, I’ve written a short manual for superBASIC. It’s available in print on Amazon.com, currently, for $5.99. It makes a useful reference if you use superBASIC; I use it all the time. It’s also available as a free ebook on most of the usual sites.1

I’ve also made some changes to how code generation works. I have changed the format of the DATASET macro, or dynamic constant. I’ve renamed %DATASETS! to !DATASETS%. I did this because I can envision having string constants as well, and I wanted to use the same format I use for variables, that is, ending in a dollar sign. So now a variable always begins with a percent, and a constant always begins with an exclamation.

The only visible change to the generated code is that I’ve standardized how blank lines get added around blocks and remarks. This greatly improves the readability of the resulting old-school BASIC.

Also, remarks no longer break on forward slashes, as these are common in URLs, which are common in the top comments I put in any program I write.

Internally, I’ve completely rewritten block generation. It generates the same code as before, but it is much easier to manage and view block types. This means that SWITCH/CASE is now the same kind of block as LOOP and IF/ELSE. LOOPs and IF/ELSE can be embedded in CASEs. Even SWITCHes can be embedded in CASEs.

This should make it easier to add an ELSEIF to IF/ELSE when needed, and to add a SWITCH ON to generate ON x GOTO statements. I probably won’t be adding any sort of FOR/NEXT loop because this turns out to be unnecessary on the Color Computer. All of the FOR loops that I’ve been wanting to BREAK out of are in subroutines, and the BREAK would have returned immediately from the subroutine. It turns out that returning from a subroutine clears out the FOR stack.

I always felt weird about jumping out of a FOR loop, leaving the poor stack perpetually waiting for a NEXT that will never come. Now that I know how Microsoft’s BASIC implemented its stack, I feel a lot better about it.

March 18, 2020: SuperBASIC for the TRS-80 Color Computer
Color Computer 2 Reverse video

The CoCo, like most computers of its era, did not have lowercase built in.

There are a lot of things I’m nostalgic for about the early era of home computers. The cameraderie. The home-brew spirit. The assumption that we were going to control the computer rather than the computer control us—there were so many cartoons making fun of the Pavlovian response to computer notifications that seem sadly prophetic today. One thing I am not nostalgic for is programming in the BASIC of the era. I wrote a lot about that in Learning to program without BASIC. BASIC programs then were a sludgy melt of undifferentiated words and numbers.

But I have an old computer, and I want to program it. It is the Tandy Color Computer 2, and it is not an easy computer to write programs on. Even the TRS-80 Model 1 could show 1,024 characters at a time, 16 lines of 64 characters. The Color Computer had half that, at 16 lines of 32 characters each. There is no holding anything but the simplest subroutine onscreen intact.

That’s part of why I wrote basicize, to help me write programs for emulators using a modern text editor on a modern computer. Not having to deal with line numbers was also a major impetus, and labeling made it a lot easier to see where the code was going. But I mainly use basicize for modifying existing code. I’ll take the code, organize it into sections, and label them. This does not help structure the code, nor does it make the code self-commenting. The variables are still one to two characters and there are no loops other than FOR/NEXT and GOTO.

It occurred to me while writing a BASIC program to examine the video modes of the CoCo 21 that I should be able to easily convert long variables into short ones using Perl. It’s practically what Perl is designed for. And simple loops? It’s BASIC because it’s basic. That should be easy.

What I ended up with is a preprocessor that makes BASIC fun again. It will take something like this:

[toggle code]

  • loop
    • loop
      • %key$=inkey$
    • endloop unless (%key$="")
    • print asc(%key$)
  • endloop
January 8, 2020: Rainbow Magazine BASIC program preflight tool
Vicious Vic by Jay R. Hoggins

Vicious Vic appears to be a variation on Robot War, with vikings in place of robots.

There are a lot of typing mistakes I make that are easily detectable: extra characters from fat fingers, mistyped parentheses, and even mistyped numbers. In an attempt to make typing BASIC programs from The Rainbow easier, as well as improve my ability to use Textastic with rcheck, I wrote this script. I wrote it somewhat haphazardly, adding new checks when I noticed that an error was detectable.

The basic idea is that since each line wraps at 32 characters, when I hit the end of the line in the Rainbow listing, I hit return. The script detects whether a line in the text file is a continuation of the previous line or a new line by looking for the line number. This solves the problem of finding a text editor that wraps at 32 characters.

But it also opens the possibility of doing some preflighting. If a line in the text file is not the final subline in a BASIC code line, it must be 32 characters long. If it isn’t, I mistyped something. And with my fat fingers, this is the most common typo. Most typos are discovered merely by making sure that each subline except the final one is exactly 32 characters.

There are also warnings, things that are probably a problem but might not be. These do not halt the program, and are displayed at the bottom of the results. They are not piped to a file, so they appear in the terminal if you’re piping.

For example, if the full BASIC line is longer than 249 characters, I probably mistyped something. That’s the maximum number of characters you can type on a new BASIC line on the Color Computer. It’s a warning, not an error, because it is possible to get more characters into a line, and it occasionally happens with the one-line and two-line contest winners, since they’re specifically trying to stuff as much into a line as possible. More than 255 characters is an error. I haven’t seen anything longer than that.1

It also checks the line number. If it isn’t greater than the previous line number, I mistyped something.2

November 20, 2019: TRS-80 Color Computer RCHECK+ in Perl
CoCo Terminal profile example

The only text editor I could find that would wrap exactly at 32 characters was vi in the Terminal.

I may be the only person who still enjoys typing in code from old books and magazines, but I do enjoy it, and enough to have written a modern version of those old books, 42 Astoundingly Useful Scripts and Automations for the Macintosh. I recently acquired a TRS-80 Color Computer 2, so I’ve been typing in old code from The Rainbow.

One of the big advantages of The Rainbow over other magazines of its era is the program RCHECK+. It’s a machine-language program that you load into memory before typing the code, and when you press the down arrow, it calculates a very simple checksum from the code you’ve typed.1 The listing in the magazine contains a series of checkpoints, such as this for TRENCH in the July 1986 issue of The Rainbow:

checkpointchecksum
7208
15178
20102
2828
3783
51188
END180

After typing line 7, the checksum should be 208; after typing line 15, it should be 178; and after typing in the entire program, it should be 180.

It turns out that this is a very simple checksum. All it’s doing is adding up the ASCII values of the code in RAM, cycling back to zero after a sum of 255. So the checksum is always from 0 to 255.2

The program is so useful that, even though I would much prefer to type BASIC code on a modern computer in a modern text editor with a modern keyboard, I didn’t.3 The values that RCHECK+ uses are the tokenized values, which means that GOTO is not G plus O plus T plus O, but rather the sum of hex 81 and A5, the tokenization of GOTO. But then I discovered that the decb program from the ToolShed suite can take a text BASIC listing and tokenize it to a standalone file.

Which makes it possible to write rcheck in Perl and run it on a text file created by decb.

  1. <- Photograph titles
  2. Text to image filter ->