Mimsy Were the Borogoves

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

Simple game menu for the Color Computer 2 with CoCoSDC

Jerry Stratton, September 7, 2022

CoCo sample menu screens

Two menu screens from MENU.BAS: some of my favorite games from The Rainbow, and some of my favorite text-based games typed in from various books.

For the true retro experience, you should, of course, access files from the command line, typing DIR to see the disk, interpreting the very abbreviated filenames, and then using RUN or LOADM to start the program. For the full retro experience, everything should be on cassette tape!

But your friends may enjoy the retro gaming experience without having any idea how to start up the games. You could, of course, put a coffee-stained sheet with helpful command-line hints next to the computer. Or, you could use this BASIC program, that leverages Darren Atkinson’s CoCo SDC floppy disk emulator to provide a simple interface to your favorite games (Zip file, 8.4 KB) saved on both the SDC’s flash slots and on .DSK disk files.

You can have as many screens as you want. The more screens, the longer it will take to load, and the more screens you (or your friends) will have to cycle through to see everything. I meant this as an easy means of showing off my favorite games; it is not meant as a comprehensive listing of everything. For a more complex file browser, see Guillaume Major’s SDC Explorer.

As written, MENU.BAS requires the SDC, but it should be able to be modified to use other solutions that store programs in ways that they can be accessed from a BASIC program.

The program attempts to respond to whatever the user might do to choose a game. If they pick up one of the joysticks, it will start following that joystick; if they use the up or down arrow keys, it will respond to them; SHIFT-up and SHIFT-down will move to the top and bottom, respectively. If they type the number corresponding to a game, the pointer will jump directly to that game.

  • 1600 REM READ STICK VERTICAL
  • 1610 REM ENABLE JOYSTICKS
  • 1620 K=JOYSTK(0)
  • 1630 FOR K=1 TO 50:NEXT K
  • 1640 IF RV<>JOYSTK(1) THEN RV=JOYSTK(1):SV=RV:GOTO 1670
  • 1650 IF LV<>JOYSTK(3) THEN LV=JOYSTK(3):SV=LV:GOTO 1670
  • 1660 RETURN
  • 1670 REM CONVERT STICK VALUE TO
  • 1671 REM ITEM
  • 1680 NC=INT(SV/(63/IC))
  • 1690 RETURN
  • 2150 REM MARK CURRENT CHOICE
  • 2160 PRINT@(CH+DO)<em>32+5,">";
  • 2170 PRINT@(CH+DO)</em>32+31,"<";
  • 2180 REM CHECK JOYSTICK BUTTON
  • 2190 SB=PEEK(65280)
  • 2200 IF SB=125 OR SB=126 OR SB=253 OR SB=254 THEN RETURN
  • 2210 REM CHECK USER INPUT
  • 2220 NC=0
  • 2230 CH$=INKEY$
  • 2240 IF CH$="" THEN GOSUB 1600:GOTO 2340
  • 2250 IF CH$="^" AND CH>1 THEN NC=CH-1:GOTO 2340
  • 2260 IF ASC(CH$)=10 AND CH<IC THEN NC=CH+1:GOTO 2340
  • 2270 IF ASC(CH$)=95 THEN NC=1:GOTO 2340
  • 2280 IF ASC(CH$)=91 THEN NC=IC:GOTO 2340
  • 2290 IF CH$>="1" AND CH$<="9" AND VAL(CH$)<=IC THEN NC=VAL(CH$):GOTO 2340
  • 2300 IF CH$="0" AND IC>9 THEN NC=10:GOTO 2340
  • 2310 IF CH$=":" AND IC>10 THEN NC=11:GOTO 2340
  • 2320 IF CH$="-" AND IC>11 THEN NC=12:GOTO 2340
  • 2330 IF ASC(CH$)=13 OR ASC(CH$)=12 OR ASC(CH$)=92 THEN RETURN
  • 2340 IF NC=0 OR NC=CH THEN 2180
  • 2350 REM CLEAR PREVIOUS CHOICE
  • 2360 PRINT@(CH+DO)<em>32+5," ";
  • 2370 PRINT@(CH+DO)</em>32+31," ";
  • 2380 CH=NC
  • 2390 GOTO 2150
  • 2400 RETURN

Both lines 1600 and 2100 start new subroutines.1 Line 1600 is a subroutine to read each joystick’s vertical value. If the new value doesn’t match the old value (RV or LV), the assumption is that the user has moved the joystick in order to choose a program. The vertical location of the joystick that was moved is converted to a position on the screen and then returned in NC (New Choice).

The subroutine at 2100 initializes the joystick and the screen (which I’ve removed from the sample above to make the new choice easier to see) and then, starting at 2180, begins the loop to check for new input.

  1. It looks at the joystick buttons; if either is pressed, a choice has been made.
  2. It checks the keyboard. If a key is pressed along the top keyboard row (the numbers 1 through 9, then 0, then a colon, then a dash), that’s assumed to be the number of the user’s choice, with 0 standing in for ten, a colon for eleven, and a dash for twelve. The up and down arrows adjust the choice up or down by one, and SHIFT-up (95) or SHIFT-down (91) adjust to the top or bottom. IC is the variable for Item Count, that is, the number of items on this screen. An ENTER (13), a CLEAR (12), or a SHIFT-CLEAR (92) return from the routine to either start the program (ENTER) or shift to a new screen (either form of CLEAR).
  3. If there is no new choice, or if the new choice matches the old choice, it returns to the top of the input loop.
  4. If there is a new choice, it clears the old choice and then goes to the display loop to display the new choice and start over again.

Choosing a game from the menu should thus be relatively easy for even a naive user to figure out, as long as they’re not afraid to touch the keyboard and/or joystick.

ENTER or a joystick’s fire button will start the chosen game. This may require a little more thought on the naive user’s part.

In a nod to OS-9, the CLEAR key switches between the various menu screens. SHIFT-CLEAR will move backwards through the screens.

  • 1140 REM CLEAR SWITCHES SCREENS
  • 1150 IF CHR$(12)=CH$ THEN CS=NS:RETURN
  • 1160 IF NOT (CHR$(92)=CH$) THEN 1200
  • 1170 CS=CS-1
  • 1180 IF CS < 1 THEN CS = SC
  • 1190 RETURN

The CLEAR key is code 12, and SHIFT-CLEAR is code 92.

Modify the names of the programs available by modifying the DATA statements in lines 3000 up. The first DATA line in each set is the title of the screen and the keyword SECTIONTITLE. Set the variable SC to the screen count—how many screens you want set up.

For subsequent lines:

  1. The first item on each line is the displayed name of the program.
  2. The second item is the file name if this is a BASIC or binary file; or the keyword MPI or FLASH if it’s a cartridge on the Multi-Pak Interface or a slot in the SDC’s flash memory;
  3. The third item is a zero or one if this is a file, indicating a BASIC program (0) or a machine language program (1); a number from 1 to 3 if this is a cartridge, indicating which cartridge slot it’s in2; or a number from 1 to 7 indicating which flash memory slot the program is stored in on the SDC.

Each screen can have up to 12 programs. For example, here are the cartridges and one binary game that I keep on the first screen:

  • 3000 REM FLASH RAM AND MPI
  • 3001 REM PROGRAMS
  • 3010 DATA RADIO SHACK CARTS,SECTIONTITLE
  • 3020 DATA MULTIPAK SLOT 1, MPI, 1
  • 3030 DATA MULTIPAK SLOT 2, MPI, 2
  • 3040 DATA MULTIPAK SLOT 3, MPI, 3
  • 3050 DATA SPACE ASSAULT, FLASH, 1
  • 3060 DATA DOWNLAND, FLASH, 2
  • 3070 DATA CANYON CLIMBER, FLASH, 5
  • 3080 DATA CHECKERS, FLASH, 3
  • 3090 DATA DUNGEONS OF DAGGORATH, FLASH, 6
  • 3100 DATA GALACTIC ATTACK, FLASH, 4
  • 3110 DATA POOYAN,COOL,POOYAN,1
  • 3120 DATA STELLAR LIFELINE, FLASH, 7

I don’t name the MPI slots, because I change those cartridges when I feel like it; the names of the cartridges are visible on the cartridge, in the MPI next to the Color Computer 2.

To make this program automatically start, you can create a STARTUP.CFG configuration file at the root of your SDHC card. The SDC will read this automatically, and load any .DSK files mentioned.

  • D=/COCO
  • 0=COOL.DSK
  • 1=UTILITY.DSK

I store utilities on a UTILITY.DSK file that I automatically load into DRIVE 1. I save this program as AUTOEXEC.BAS on the utilities disk. The SDC sees that filename on one of the autoloaded .DSK virtual disks and runs it automatically after it loads the disks listed in STARTUP.CFG.

I store my favorite games on a .DSK file named COOL.DSK. These are all, or almost all, typed in from old Rainbow magazines, which is why the menu at the bottom says “CLEAR for Rainbow Games”.

CoCo Game Menu main screen

“Rainbow Games” is the section title of the second screen, and the menu program automatically displays the next screen in the rotation.

Note that only UTILITY.DSK is required by the menu; the menu program will automatically try to load any other DSK referenced in the DATA lines onto drive 0.

  • 1700 REM RUN FROM DISK
  • 1710 IF LO$ = "UTILITY" THEN DR=1 ELSE DR=0
  • 1720 DRIVE DR, LO$ + ".DSK"
  • 1730 DRIVE DR

I wrote this code using my own superBASIC. It made it a lot easier to keep the code readable. If you want to modify the code, you may find it easier to modify the simpler superBASIC source than to modify the running BASIC code. That said, one of my goals for superBASIC was that it create easily readable code, so you should be able to edit its BASIC just as easily as or even more easily than any other BASIC code you haven’t written yourself.

Here’s the code for the first screen, the one I used as an example above:

[toggle code]

  • # Flash RAM and MPI programs
  • data maxlines 13
    • Radio Shack Carts,sectionTitle
    • Multipak Slot 1, mpi, 1
    • Multipak Slot 2, mpi, 2
    • Multipak Slot 3, mpi, 3
    • Space Assault, flash, 1
    • Downland, flash, 2
    • Canyon Climber, flash, 5
    • Checkers, flash, 3
    • Dungeons of Daggorath, flash, 6
    • Galactic Attack, flash, 4
    • Pooyan,cool,POOYAN,1
    • Stellar Lifeline, flash, 7
  • enddata

The code starts with “data maxlines 13”, which (a) marks the beginning of a section of DATA, and (b) will generate an error if there are more than 13 lines—1 for the section title and 12 for the displayed programs.

Among the features that using superBASIC enables are having a special holiday menu just for the holidays, and including a speech subroutine for using the Speech/Sound cartridge. I have a section of special code for including speech cartridge support, a Christmas menu, and a Fourth of July menu.

[toggle code]

  • #IFDEF fourth
    • # Patriotic Programs
    • data maxlines 13
      • God Bless America!,sectionTitle
      • American Flag,rain87,FLAG,0
      • Fourth Celebration,rain84b,FOURTH,0
      • Patriotic Songs,holidays,USSONGS,0
      • Star-Spangled Banner,holidays,SSBANNER,0
    • enddata
  • #ENDIFDEF

Near the fourth of July, I regenerate the BASIC using the “fourth” switch:

  • \
  • superbasic --switch fourth menu.txt > MENU.BAS

This turns on any code between #IFDEF fourth … #ENDIFDEF, which means those four programs now get their own screen and will display as the second screen.

And, of course, because I have a Speech/Sound cartridge, I’ve programmed it to speak “Greetings, Professor. Shall we play a game?” on startup.

[toggle code]

  • #IFDEF speech
    • #INCLUDE speech.bas
    • %speech$ = "Greetings, Professor."
    • gosub speakSpeech
  • #ENDIFDEF
  • gosub getGameScreens
  • %currentScreen% = 1
  • #IFDEF speech
    • %speech$ = "Shall we play a gayme?"
    • gosub speakSpeech
  • #ENDIFDEF
  • sub runFromMPI
    • #IFDEF speech
      • gosub disableSpeech
    • #ENDIFDEF
    • poke 65407,(%slot%-1)*17
    • exec &HC000
  • endsub

There are three sections to enabling speech:

  1. It includes the speech code, and then immediately speaks “Greetings, Professor.”
  2. After it loads the screens, it speaks “Shall we play a gayme?”3
  3. Finally, if loading a program from the MultiPak Interface, it will disable the speech code, because otherwise it might interfere with the cartridge code.

I use the following to generate a menu for my own CoCo:

  • superbasic --switch speech Personal/menu.txt > Utilities/AUTOEXEC.BAS

This switches speech on in the final code, and saves it to AUTOEXEC.BAS, where it will be copied into UTILITY.DSK.

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.

  1. While these line numbers reflect the numbers in the actual program at the time of writing, as I update the code they may change, especially since I update the code in a superBASIC source file and then convert it to the CoCo’s BASIC.

  2. Cartridge slot 0 is where the SDC is assumed to be.

  3. The odd spelling of “game” is necessary to get a correct pronunciation.

  1. <- BASIC tokenization