TRS-80 Color Computer RCHECK+ in Perl
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:
checkpoint | checksum |
---|---|
7 | 208 |
15 | 178 |
20 | 102 |
28 | 28 |
37 | 83 |
51 | 188 |
END | 180 |
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.
There was a lot of trial and error getting this to work. I don’t have the listing for RCHECK+, so I can’t know for sure what the algorithm is. But poking at it on the CoCo by adding, removing, and altering strings, BASIC statements, and line numbers, and watching how the checksum changes, I’m pretty sure I have it. It certainly works on the BASIC code I’ve tested it on so far. But there are no guarantees.
Here’s what it looks like using it:
- $ ~/bin/rcheck TRENCH.BAS 7 15 20 28 37 51
- 7: 208
- 15: 178
- 20: 102
- 28: 28
- 37: 84
- 51: 224
- END: 223
Clearly, I went south sometime after line 28.4
You don’t need to give rcheck the checkpoint lines. If you leave them out it will only report the final checksum, which is the behavior of the original rcheck+ in the Rainbow. I find being able to type through a full column without losing the checksums in between very useful, however.
[toggle code]
- #!/usr/bin/perl
- # run the Rainbow checksum against a BASIC text file
- # requires decb to tokenize the BASIC
- # Jerry Stratton http://www.hoboes.com/Mimsy/hacks/coco/
- use File::Temp qw/tempfile/;
-
while ($option = shift) {
-
if ($option eq '--debug') {
- $debug = 1;
-
} elsif ($option eq '--rcheck') {
- $useOriginalRcheck = 1;
-
} elsif ($option eq '--help') {
- help();
-
} elsif ($option =~ /^[1-9][0-9]*$/) {
- $checksumLines{$option} = 1;
-
} elsif (!$basicFile && -f $option) {
- $basicFile = $option;
-
} else {
- help("Unknown option $option");
- }
-
if ($option eq '--debug') {
- }
- help("No input file provided.") if !$basicFile;
- # first, tokenize the BASIC file
- ($tokenHandle, $tokenFile) = tempfile(UNLINK=>1);
- `/usr/local/bin/decb copy -b -t "$basicFile" "$tokenFile"`;
- print `hexdump -C $tokenFile` if $debug;
- # then read the tokenized file
- # character zero marks the end of a line, and thus also the beginning of a line
- open $codeHandle, $tokenFile or die("Can't open $tokenFile: $!");
- $code = do { local $/; <$codeHandle> };
- close $codeHandle;
- # finally, loop through the tokenized code and add up each character
- $counter = -2;
-
while ($counter < length($code)) {
- $counter++;
- #will be zero when $counter is -1
- $character = substr($code, $counter, 1);
- $addend = ord($character);
- #line numbers need to be handled specially
- #character 0 marks the end of a line
-
if ($addend == 0) {
- #advance to line number
- $counter += 3;
- #calculate line number
- my $linePartOne = ord(substr($code, $counter, 1));
- my $linePartTwo = ord(substr($code, $counter+1, 1));
- $line = $linePartOne*16*16 + $linePartTwo;
- #use the tokenized line number for the checksum
- $addend = $linePartOne + $linePartTwo;
- #advance past the line number
- $counter +=1;
- }
- print "$previousLine:\t", checksum(), "\n" if ($debug || $checksumLines{$previousLine}) && $previousLine ne "" && $line != $previousLine;
- $sum += $addend;
- $previousLine = $line;
- }
- print "END:\t" if $debug || %checksumLines;
- print checksum(), "\n";
-
sub help {
- $message = shift;
- print "$0 [--debug] [--help] [--rcheck] <BASIC file to checksum> [<line numbers to report>]\n";
- print "\trcheck: use the original rcheck algorithm instead of rcheck+\n";
- print "$message\n" if $message;
- exit;
- }
-
sub checksum {
-
if ($useOriginalRcheck) {
- return sprintf('%04X', $counter - 1);
-
} else {
- return $sum%256;
- }
-
if ($useOriginalRcheck) {
- }
Save the script as rcheck. You may find my edit script for 42 Astounding Scripts useful for pasting this or any scripts into TextEdit or your favorite text editor.
As you can see, besides requiring that decb be installed on your computer, the only tricky part of the program is detecting where BASIC lines begin. CoCo BASIC uses the null character, character zero, to mark the end of a line. So I have the script look for character zero, grab (and sum) the line number, and then skip ahead to after the line number. This is probably not completely kosher, but it works so far. I’m ignoring two bytes that are probably important.
And, in order to successfully report on the first line, I set the counter to -1. Since there is no character at -1 in any string, it comes out as null, and the script thinks that the very first line is preceded by an end-of-line marker.
In the original RCHECK+, it was critical to verify the checksums every time you reached a checkpoint; it was difficult to see previous checkpoints. You had to delete lines of code. With this program, if you prefer to type in the whole program and then debug, you can do it. Just provide the checkpoints to the script, and then you can type as much as you want. Later, you can go through each checkpoint one at a time fixing any discrepancies in that section.
One of the nice things about such a simple checksum is that the discrepancy is often a clue to what the problem is. Very often, I find that if I’ve checked and double-checked the code and the number still doesn’t match, it is because I left out a character, probably on the last line. Often, this is obvious. There’s a space at the end of a line which is of course invisible in the printed listing, and the checksum is 32 less than what it’s supposed to be.5
In BASIC, of course, the way to check which character is missing is to use CHR$(VALUE) where value is the discrepancy. While typing in TRENCH, I was going crazy thinking I had something wrong with the rcheck script, checking over and over and not finding anything wrong with the code. It was low by 41; because the script can provide the checksum on multiple checkpoints (a distinct advantage over the original RCHECK+), I decided to go ahead to the next checkpoint. It was still 41 low. It was very clear that the problem was not with the script but with my typing.
What is character 41? In Chipmunk BASIC:
- $ basic
- Chipmunk BASIC 368b1.07
- >print chr$(41)
- )
- >
The missing character was almost certainly a close parentheses.6 Since I clearly couldn’t be missing a close paren except on the last line—it would have been obvious from the 32-character width—I checked and found the error in less than a minute.
Yes, 32-character width. The other advantage to Rainbow listings is that they were 32-characters wide, and matched exactly7 what should be on screen. This is helpful enough that I emulate it on the Mac by using vi in the Terminal. I’ve created a special Terminal profile for 32-character width typing.
I tried to use my GUI text editors, but they all want to wrap intelligently, that is, at word boundaries. I couldn’t figure out how to tell TextEdit, Textastic, or TextWrangler to simply wrap at the end of the line regardless of word boundaries.
REMEMBER ALSO TO USE CAPS LOCK when typing but TURN IT OFF when done. It will make it a lot easier to find typos if your screen matches exactly what is in Rainbow magazine. But if you leave CAPS LOCK on while in VI’s command mode, the commands you get will not be the commands you expect.
You may also find the “+” key useful for moving to the beginning of the next line in vi. Just using the down arrow will move to the same location in the next line that you are in this line.
The only thing I haven’t figured out how to do is have a better visual or audio cue when the line wraps at 32 characters. When typing directly on the CoCo, the screen is big enough that even while looking at the listing in the magazine I can see the line wrap out of the corner of my eye—the entire screen shifts up one, after all. If I don’t see the shift out of the corner of my eye, I know that I typed too little (or, if the shift happens too soon, I typed too much). This effect is much less pronounced on a modern screen. Having a bell sound when vi wraps a line would be great, but I don’t see how to do it, or even if it’s possible. The problem is exacerbated by vi’s inability to partially scroll the top visible line. If the top line of code takes up four screen lines, then vi will scroll up by four lines. The next word wrap won’t even need to scroll.
In response to TRS-80 Color Computer Programming Tools: The TRS-80 Color Computer was a fascinating implementation of the 6809 computer chip, and was, from the Color Computer 1 through 3, possibly the longest-running of the old-school personal computers.
- November 11, 2020: New, improved rcheck+ for Rainbow Magazine code
-
I’ve added a few new features to the rcheck script to make it more useful for typing in code from The Rainbow.
--debug provide a hexdump of the tokenized BASIC file --rcheck use the original rcheck rather than rcheck+ --shift <x> shift all checksums by x --verbose show 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.
I considered providing a similar program for Astounding Scripts, but the advantage of modern scripting languages over BASIC—their readability—also makes it more difficult to ensure that typists use exactly the same characters, especially spaces and tabs, as in the original.
↑And, importantly, order of values didn’t matter. This is not as bad as it could be because if you transpose letters in a BASIC keyword, the value of the keyword changes. But I had a vicious problem with Vicious Vic in the July 19867 issue because I mistyped the variable MN as NM. The rcheck algorithm reported the correct checksum, but the program failed until I was able to hand-trace the code to figure out why the it was trying to get a CHR$ of a negative number.
↑Ed Snider’s CoCo SDC combined with the decb program makes it easy to copy files via SD card between modern computers and CoCos.
↑And you may find the aligntabs script from 42 Astoundingly Useful Scripts and Automations for the Macintosh useful for aligning the numbers. Just pipe it through: ~/bin/rcheck TRENCH.BAS 7 15 20 28 37 51 | aligntabs.
↑Or, if the author had the habit of adding spaces to the end of lines, a multiple of 32. It’s important to remember that the difference between upper and lower case—or reverse text in the case of Color Computer programs—is also 32. Reverse case is often used to emphasize some text. And sometimes in obscure locations such as comments.
↑The same method, using CHR$(), would work in Extended Color BASIC itself, either on a real CoCo or in an emulator such as XRoar.
↑Barring strange printer artifacts such as replacing reverse text with lowercase. I think the up arrow printed differently as well, though I may be misremembering the Model I.
↑
- 42 Astoundingly Useful Scripts and Automations for the Macintosh
- MacOS uses Perl, Python, AppleScript, and Automator and you can write scripts in all of these. Build a talking alarm. Roll dice. Preflight your social media comments. Play music and create ASCII art. Get your retro on and bring your Macintosh into the world of tomorrow with 42 Astoundingly Useful Scripts and Automations for the Macintosh!
- CoCo SDC: Ed Snider at The Zippster Zone
- Ed Snider and Darren Atkinson’s SD card program pak for the Color Computer 1, 2, and 3 allows you to store all of your code on an SD card, emulating a disk drive so that the DSK files are compatible with any CoCo program that uses disk drives. It is phenomenal.
- Edit (Zsh)
- One of the first scripts in the book is a script to edit scripts. But that elicits a bootstrapping problem. Without the edit script, you can’t use the edit script to edit the edit script!
- An Introduction to Display Editing with Vi: William Joy and Mark Horton
- “Vi (visual) is a display oriented interactive text editor. When using vi the screen of your terminal acts as a window into the file which you are editing.”
- The Rainbow Magazine July 1986 at Internet Archive
- Containing The Evictor, Vicious Vic, and Trench, among many other programs.
- rcheck+ for macOS (Zip file, 2.5 KB)
- Verify Rainbow Magazine rcheck checksums on the Macintosh command line.
- ToolShed (os9 & decb)
- “ToolShed brings you the ease and speed of developing these programs to your modern personal computer running Windows, Mac OS X or Linux. The tools in the shed consist of a relocatable macro assembler/linker and intermediate code analyzer, a stand-alone assembler, an OS-9/Disk BASIC file manager and more.”
- XRoar—Dragon & CoCo emulator
- “XRoar is a Dragon emulator for Linux, Unix, Mac OS X and Windows. Due to hardware similarities, XRoar also emulates the Tandy Colour Computer (CoCo) models 1 & 2. More features.”
More Color Computer
- Simple game menu for the Color Computer 2 with CoCoSDC
- This simple menu provides one screen for cartridges saved in the CoCoSDC’s flash ROM, and any number of screens for your favorite games for your friends to play.
- Rainbow Magazine preflight tool enhanced
- I’ve added several features to the Rainbow Magazine preflight tool, including a check for references to line numbers that don’t exist.
- CoCoFest! 2021
- Forty years later, I finally make it to CoCoFest!
- BASIC tokenization examined
- Why do old BASIC programs have strange characters in their .BAS files? Why do they look like they’re compiled code?
- What are the 8 bits in 8-bit computing?
- Retro computing is often called 8-bit computing. This is because the bytes that these computers use are composed of eight bits, and much of what the computer does is operating on these individual bits, not on the byte as a whole.
- 19 more pages with the topic Color Computer, and other related pages
More The Rainbow magazine
- Rainbow Magazine preflight tool enhanced
- I’ve added several features to the Rainbow Magazine preflight tool, including a check for references to line numbers that don’t exist.
- 8 (bit) Days of Christmas: Day 1 (Do You Hear What I Hear?)
- For day 1 of the 8 (bit) days of Christmas, John Mosley’s “Do You Hear What I Hear?” from the December, 1987, Rainbow Magazine. Mosley coaxes four-voice music out of the CoCo 1 and 2 using a machine-language program.
- 8 (bit) Days of Christmas: Day 10 (Up on the Rooftop)
- In the December 1986 Rainbow, J. D. German presented us with this game, involving flying and landing Santa to deliver presents!
- 8 (bit) Days of Christmas: Day 11 (O Christmas Tree)
- Day 11 of the 8 (bit) days of Christmas is the graphic accompaniment to “O Tannenbaum” from Robert T. Rogers “Holly Jolly Holidays”, from December 1984.
- 8 (bit) Days of Christmas: Day 100 (Hearth)
- Lower resolution graphics were more appropriate for animation, because you could page through up to eight screens like a flip book. This is Eugene Vasconi’s Holiday Hearth from December 1986.
- Five more pages with the topic The Rainbow magazine, and other related pages
December 11, 2019: I’ve added an option to run the original rcheck instead of the far better rcheck+. The rcheck+ algorithm is a real, if primitive, checksum. The original rcheck just checked how much RAM the typed program was using. This wouldn’t pick up many errors that didn’t already get picked up by just watching when the cursor flipped to a new line.
Use --rcheck to run the original rcheck on a file.
As you can see, the original used hexadecimal totals, and the number always rises.