Convert PCBASIC code to TRS-80 Extended Color BASIC
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.0 KB).
- 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 anyPRINT 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. - The IBM PC uses a bare
RND
function to generate a random number between 0 and 1. Extended Color BASIC usesRND(0)
for the same. Most of the time, Hartnell usesRND
to generate an integer, by multiplying the real number by a whole number and taking theINT
of that. The format and variations are complex enough that I chose not to try and convert that to ECB’s cleanerRND(x)
function. Hartnell’s random numbers usually start at zero, whereas theRND(x)
function starts at 1. - The IBM PC has a
RANDOMIZE
statement to set the random number generator’s seed. Extended Color BASIC uses theRND
function to do the same thing, by using negative numbers. Where the number Hartnell sends toRANDOMIZE
is easy to discern, the script uses the same number inRND(x)
, but negative. Where the number is not easy to discern, the script discards it and usesRND(-TIMER)
. - The IBM PC can
RESTORE
to a specificDATA
line, using, for example,RESTORE 3270
so that the nextREAD
starts with the data in line 3270. The script emulates this in Extended Color BASIC by first doing aRESTORE
and then reading up to but not including the data in the specified line. This is a lot slower, but it does work. - The IBM PC can use BASIC function names at the start of a variable name. Extended Color BASIC cannot. The script attempts to detect bad variable names and replace them. Fortunately, using only a function name as a variable name is illegal in PC BASIC as well.
- The Color Computer sees everything following a DATA statement as data, even if there’s a colon on the line. This mainly seems to be a problem with REM statements, an easily solvable problem, since they can be safely removed.
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.
For PRINT
statements that are repeated on the same line, the script combines the strings from each of the PRINT
statements into a single PRINT
. If the resulting string is more than 32 characters the script takes the string and generates multiple PRINT
statements in its place.
Further, since the Color Computer has far fewer vertical lines than the PC did, I have the script discard repeated empty PRINT
statements. They serve little purpose on the CoCo except to scroll important information off the screen.
And finally, if there are still more than 14 sequential PRINT statements, it adds a pause subroutine at the end, and warns you about it, calling the pause routine before the number of PRINT statements exceeds 14.
As you can see from the Mistress of Xenophobia screenshot, it’s far from perfect. Any PRINT
line that contains variables is impossible to predict the size of, so in Mistress the “grovelling peasants” line is separate from the “some xx acres” line. In real life, of course, I’d go in and manually merge those two lines. In real real life I liked this game so much I rewrote it in superBASIC. The screenshot here is from the auto-converted version, not the superBASIC version.
One change requires a warning. I was somewhat surprised to find that Extended Color BASIC has no DEFINT
statement to mark certain variables as integers instead of floating-point numbers. So the script removes that statement entirely and issues a warning that you may need to verify that all of the listed variables are used as integers. It could be a problem if the code has a line like A=B/2
and the program is expecting that A will always be an integer.
Original Code | CoCo Translation |
---|---|
|
|
|
|
In The Duke of Dragonfear, the PRINT
statements following the CLS
are removed; the RND
statement is changed to RND(0)
, and the menu of options is shifted around a bit without doing much. In Mistress of Xenophobia, the three PRINT
statements under the CLS
are removed, leaving the line empty, and the opening instructions are reformatted to fit on the Color Computer’s screen—otherwise, it would have wrapped in an ugly manner toward the end of the first line. And various repeated empty PRINT
statements are collapsed into a single empty PRINT
.
One of the more interesting features of this program is the --compress option. This attempts to remove all unnecessary code, lines, and spaces, as well as abbreviate text. Hartnell’s “Chateau Gaillard” from Creating Adventure Games on Your Computer• is 29,520 bytes ASCII, and 24,932 bytes tokenized. This, combined with the strings it creates, is too big to run in 32k on the Color Computer.1 Compressed, however, it drops to 23,489 bytes ASCII and 19,626 bytes tokenized. This is a more than 20% reduction in memory requirements. That’s just barely enough to let it run.
The compress option has three levels. All of the code changes happen at level 1.
- Remove REM text. If the REM statement is at the end of a line of code, it removes the REM statement as well. If the REM statement is on its own line, it only removes the statement if no THEN, GOTO, or GOSUB references that line.2
- Combine DATA lines, up to 255 characters per line. Also, remove zeroes from numeric DATA lines. An empty data element gets read as zero, so this saves a byte.
- Combine multiple lines into one unless it detects that (a) this would cause code to never be executed (such as following an IF line) or (b) the line is referenced elsewhere.
- Remove spaces from around statements and functions. In most cases, spaces are unnecessary. Spaces are necessary if a numeric variable that ends in a letter is followed by a statement; this should only be the case with THEN, as in IF A=I THEN GOTO 500. This can be compressed to IFA=I THENGOTO500, but that one space is necessary to keep it from looking like the variable ITHEN to the BASIC interpreter.
- Convert THEN GOTO and THEN GOSUB to just GOTO and GOSUB.
- At level two, it will abbreviate text, by combining NOT and HAVE into contractions, removing multiple spaces, getting rid of spaces around dashes, converting ellipses into two periods, and changing AND to the ampersand.
- At level three, it gets a bit more creative with contracting and abbreviating text. Any word followed by ARE is contracted to the word plus ’RE. The same is done with words followed by HAS or IS. Some longer words are converted to shorter words with similar colloquial meanings; currently, that’s limited to ALTHOUGH being changed to THOUGH and CONGRATULATIONS to CONGRATS. This is mainly because I have so far only used this feature with Chateau Gaillard. It’s the final and longest program in Creating Adventure Games•.
Here’s how the various levels help compress CHATEAU.BAS:
Level | Bytes | Tokenized | Reduction |
---|---|---|---|
0 | 29,520 | 24,932 | |
1 | 23,867 | 19,976 | 19% |
2 | 23,602 | 19,735 | 20% |
3 | 23,489 | 19,626 | 21% |
It may not seem like much of a difference between level 1 and 3, but it was enough to get Chateau Gaillard to successfully run. By default, the script uses compression level 1 when you specify compression on the command line. If you don’t specify compression, it performs none.3
With what I learned from implementing compression here, I’ll probably add a similar option to superBASIC when it becomes necessary. Or more likely, write a separate script that superBASIC’s output can be piped to or that can be given any text file as an option.
Remember that you can also gain 4,608 bytes by typing PCLEAR 1 before loading a program.4
The original reason I wrote this script was to do some simple error checking after typing in Hartnell’s BASIC programs. It performs a lot of useful checks to catch common and computer-recognizable typos. If you want that feature and not the CoCo conversion, add --nococo to the command line.
The very first error check I added was checking that line numbers were in increments of 10. All of Hartnell’s code in this book uses increments of 10, exactly, throughout each program. If you want to disable that check, add the --uneven-lines switch. I often do this after I’ve typed in the code, and start adding my own modifications. Such as in The Bannochburn Legacy where Hartnell makes the very strange decision to check for the starting letters of “fight” and “flee” but requires entering single letters for going north, south, etc.5
Other checks are:
- Is the line too long? This mostly occurs after forgetting to hit return at the end of a line, since PC BASIC has the same 255-character limitation as ECB.
- Has the same line number already occurred? Most likely a typo.
- Is there an odd number of quotes? While PC BASIC supports leaving the last quote off of a line, I have seen this so rarely in Tim Hartnell•’s code that it looks like a typo, and I fix it.
- Are there mismatched parentheses? If the number of open and close parentheses don’t match, that’s likely a typo.
- Does an assignment follow a comma, semicolon, or quote rather than a colon? That’s almost certainly a typo.
- Does an assignment, not at the beginning of a line, not have a colon in front of it? Also almost certainly a typo.
- Does the line number referenced in a GOSUB, GOTO, or THEN exist? This is either a typo here, or in the referenced line.
- Does a statement following a quote not have a colon in front of it? For some reason, I often leave the colon out after a close quote and before the next statement.
I find it easiest to test the code in Rob Hageman’s PC-BASIC before converting it to Extended Color BASIC. After converting it to ECB, I test it in XRoar before transferring it to the Color Computer. That’s also where I get the screenshots.
This script highlights the benefits of just-in-time programming. If I’d followed the advice of, say, Paul Nagin in BASIC with Style, and attempted to first formulate “a complete understanding of the problem and a complete general plan of attack”, I would probably never have written this script. The problems would have seemed insurmountable. As it was, my initial reaction on discovering that there are no reserved words6 in PC BASIC, causing syntax errors in ECB, was to simply give up with a fatal error on detecting them. But since I had already solved the problem of separating quoted text from BASIC code, I didn’t have to worry about avoiding replacing, say, the word COST when it was in quoted text. There are almost certainly still killer issues to be dealt with; but in the meantime I’ve been able to have a lot of fun playing games I would otherwise have had to painstakingly convert by hand.
There’s no reason why this script couldn’t be used for other books that use PCBASIC, or similar BASIC variants, as their lingua franca. As long as there are no conflicting conversions, the conversions can be added to the statementConversions subroutine. The script sends every statement, without any quoted text, to that subroutine after breaking lines apart on colons.
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.
I have a feeling it’s mainly too big to run in Disk Extended Color BASIC. Also, I suspect that if I’d known about PCLEAR when I typed this program in, I wouldn’t have needed some of the uglier text abbreviations.
↑Interestingly, to me at least, while an apostrophe in place of REM takes up much less space in ASCII, it takes up one extra byte per use after tokenization. Tokenizing CHATEAU.BAS using decb -b -t created a 19,976-byte file with REMs and a 20,034-byte file with apostrophes. Similarly, PRINT MEM in Xroar returned 2,859 bytes free with REMs and only 2801 bytes free with apostrophes.
In both cases, that’s a difference of 58, which is exactly the number of lines that had a REM statement but couldn’t be deleted (at least not without updating all the references, which may be workable) due to being referenced elsewhere.
↑At the end of the process, I also saved 115 bytes by using RENUM 1,20,1 to renumber the lines in increments of 1, starting at 1. My Color Computer has 22,973 bytes free after a NEW. After loading the fully-compressed “Chateau Gaillard” it had 3,345 bytes free. And after renumbering the lines, it had 3,460 bytes free.
When working in really tight memory, the amount of memory cleared for string space also matters. CLEAR 100 before running the program, or not clearing any memory, resulted in an OM (Out of memory) error; CLEAR 50 seems to work, and clearing something less than 50 results in an OS (Out of string space) error. Amazing how little string variables these programs used.
I also discovered that putting a CLEAR in a subroutine clears the return stack as well, resulting in an RG (RETURN without GOSUB) error.
↑For reasons I don’t understand, PCLEAR 1 fails with an FC error sometimes, if executed after loading, which means it can’t be put in as the first line of some programs. For the Chateau, PCLEAR 2 still saved 3072 bytes, which was more than enough to run after compression level 2.
↑I see what he’s doing there, sort of. He chose the words “fight” and “flee” for those actions, in order to make the semi-combat actions start with the same letter. But it has the effect of allowing for typing FIGHT and FLEE but not SOUTH or NORTH, or MAGIC or STRENGTH.
↑Or at least fewer reserved words. Even in PC BASIC, you can’t use a function name for a variable name. The problem is that in ECB you can’t start a variable name with a function name; so in PC BASIC COS is illegal but COST is legal. In ECB, both are illegal.
This has the benefit that no PC BASIC program should use a function name for a variable name—except that there are ECB reserved names that don’t exist in PC BASIC—in Hartnell’s Chateau Gaillard, he uses AS as a numeric variable. This is a reserved word in ECB (in Disk BASIC, to be precise). If you run into one of those, there’s not much you can do except change them by hand. Automatic replacement would run the risk of changing legitimate uses of the function.
↑
- 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!
- Creating Adventure Games on Your Computer•: Tim Hartnell (paperback)
- “If I had read this back in 1983 or 1984 when it came out, I would have spent all my time writing adventure games. Even now it’s got me thinking about how to use the same techniques in sqlite/Python. Hartnell describes clearly the techniques used to keep track of rooms and exits, and goes through each technique line-by-line. ”
- PC-BASIC: Rob Hagemans
- “Free, cross-platform emulator for the GW-BASIC family of interpreters… Technology of the 1980s—available here and now.”
- PCBASIC to CoCo ECB conversion script (Zip file, 6.0 KB)
- Inspired by Tim Hartnell’s Giant Book of Computer Games, this converts, for the most part, PCBASIC into Extended Color BASIC.
- Review of Tim Hartnell’s Giant Book of Computer Games: Jerry Stratton at Jerry@Goodreads
- All of the programs are amazingly small, and easily typed in. There are adventures, puzzles, chess, and checkers, plus a lot of other games. The text is readably large. The code is generally well-designed and the logic, at least for the less complex games, easy to follow.
- SuperBASIC for the TRS-80 Color Computer
- Make BASIC Fun Again. Use loops, switches, and subroutines while writing Extended Color BASIC code for the Radio Shack Color Computer.
- Tim Hartnell’s Giant Book of Computer Games•: Tim Hartnell (paperback)
- This is a collection of purely text games from about 1983. Most of the games should benefit from adding graphics to them, and that’s the assumption, that you’ll add whatever graphics your own computer supports. The code is “in Microsoft BASIC on an IBM PC”. The only restrictions are memory: some of them won’t fit in 4k: chess requires 8k, and one of the adventure games requires 17k.
- 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 BASIC
- 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.
- BASIC tokenization examined
- Why do old BASIC programs have strange characters in their .BAS files? Why do they look like they’re compiled code?
- Read BASIC out loud
- Reading BASIC out loud is a great tool for verifying that what you’ve typed in from an old-school magazine or book is correct.
- SuperBASIC for the TRS-80 Color Computer
- Make BASIC Fun Again. Use loops, switches, and subroutines while writing Extended Color BASIC code for the Radio Shack Color Computer.
- Rainbow Magazine BASIC program preflight tool
- This script takes 32-character lines typed in from Rainbow Magazine BASIC listings and assembles them together into full BASIC lines, doing some rudimentary error-checking along the way.
- Six more pages with the topic BASIC, and other related pages
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