Category Archives: CoCo

Tandy/Radio Shack TRS-80 Color Computer (CoCo)

Request: Pictures of CoCo 1/2 on a TV, and CoCo 3 on TV/CM-8

YouTube has been showing me videos from a channel called CoCo Town lately. This one, posted recently, focuses on emulators not getting the CoCo screen’s aspect ratio correct:

CoCo Town YouTube video.

I noticed that the recent XRoar emulator also changed its aspect ratio. It just felt “wrong” to me since I have basically only used XRoar for the past few years. Also, my CoCo 3 has been using a VGA monitor via the Cloud-9 FPGA VGA adapter. I have no idea how accurately it represents the CoCo output, but I know it is recreating it and making it fit on the VGA monitor.

With that in mind, I have a favor to ask. Can someone out there with a CoCo 1 or 2 hooked to a TV set send me a photo of what it looks like on your TV set? A front view of the startup green screen would be ideal.

Likewise, I’d like to see what the CoCo 3 looks like on an analog RGB monitor like the CM-8. I recall the CoCo 3 was very off center using the TV output, but if you can get a picture of that too, I’d appreciate it.

Thanks, much!

The 9 colors of the CoCo’s high resolution screens…

I was today year’s old when I realized the CoCo’s high-resolution color values actually make sense.

Let me just get this right out in the open…

“I feel dumb I never realized the PMODE colors in the manual were correct.”

– Allen

You all probably knew this. If I did, I forgot I knew it. And I really don’t think I ever knew it. Because dumb.

My first CoCo was a grey TRS-80 Color Computer that I got around 1984. Today we call it a “CoCo 1” but back then it was the only CoCo.

The CoCo had eight colors (nine if you count black) that it could display:

Color Adjustment Test Display, Radio Shack TRS-80 Color Computer Quick Reference Guide, page 55.

The colors are listed as:

  • 0 – Black
  • 1- Green
  • 2 – Yellow
  • 3 – Blue
  • 4 – Red
  • 5 – Buff (I always called it white)
  • 6 – Cyan
  • 7 – Magenta
  • 8 – Orange

When you use the high resolution graphics (PMODEs), you have a choice of a higher high-resolution with 2 colors, or lower high-resolution with 4 colors. Each of these modes has two color sets, which select which 4 or 2 colors you can use on the screen. Here is how the Extended Color BASIC manual describe the PMODEs:

There are some high resolution graphics commands that let you specify a color — such as the COLOR, CIRCLE and DRAW — let you specify a color value to use. I found it odd that the color value was listed as “0-8” — as if you could use nine colors on a high resolution screen. You can’t! Only four, or two.

But the manual listed nine colors, anyway:

The first dumb thing I never realized until today was those high-resolution color numbers are the same as the ones for the text screen, as used by text commands CLS and SET. As I previously wrote about, I also did not realize that the colors available on the high resolution screens were actually the same as the ones on the text screen. I’d never seen them at the same time, and they always “looked different” to me.

But why did Microsoft let you specify color values 0-8 for a screen that can only have four colors? When I started playing with the CoCo again as a grown-up, I assumed Extended Color BASIC must have been ported from a system with more colors and they just left it as-is.

But the manual was weird about it. For example, it would tell you use use colors 5, 6, 7 and 8!

“If you want to try changing the dots’ colors, use buff (5), cyan (6), or magenta (7). Then change the color back to orange (8) before proceeding…”

– Extended Color BASIC manual, page 86

But I knew back then that this was just silly. If you used colors 1, 2, 3 and 4 in one mode, you could also use colors 1, 2, 3 and 4 in the other color set. You’d get the four unique colors in each mode, just different colors based on the mode. (Or you could use 0, 1, 2 and 3 just shifting the order over.)

The important part of the manual was listing which four colors you got when you used SCREEN to specify the color set to use:

SCREEN 1,0 gave you the green/yellow/blue/red colors on a green screen with green border, and SCREEN 1,1 gave you the buff/cyan/magenta/orange colors on a buff screen with a buff border.

Then, there were the higher high-resolution modes that only had two colors. The manual mentioned them (and the four color modes) later:

I guess they were introducing things slowly as you progressed through the chapters.

In a 2-color mode, SCREEN 1,0 gives you a green border with black background and you can draw in green. SCREEN 1,1 gives you a black screen with a white background and you can draw in white.

And my mind was blown when I realized that, though you could use 1-4 on any 4-color screen, or 1-2 on any 2-color screen, and get different colors, the way the manual tried to teach us was basically: “In this mode, use colors A to B. In that mode, use colors C to D” and so on.

Behold! PMODE 3,1:SCREEN 1,0 5-color mode showing what it draws for all 9 colors (0-8):

If you use the color chart, you can see you should be using colors 1-4:

  • 1- Green
  • 2 – Yellow
  • 3 – Blue
  • 4 – Red

If you go to PMODE 3,1:SCREEN 1,1 you get these colors:

And here is why the manual told you to use colors 5-8:

  • 5 – Buff
  • 6 – Cyan
  • 7 – Magenta
  • 8 – Orange

And in the 2-color mode, if you went PMODE 4,1:SCREEN 1,0 you would get the same two colors repeated over and over:

And that corresponds to using colors 0 and 1 in the chart:

  • 0 – Black
  • 1- Green

And PMODE 4,1:SCREEN 1,1 looks like this:

Here, you would want to use colors 0 and 5:

  • 0 – Black
  • 5 – Buff

I don’t know if ANY of us ever programmed using the numbers like that — mostly because the manual really did not make it clear which colors were part of which mode. You’d need a fancier chart that showed what you could do, like:

PMODESCREEN0
Black
1
Green
2
Yellow
3
Blue
4
Red
5
Buff
6
Cyan
7
Magenta
8
Orange
0 or 20XX
0 or 21XX
1 or 30XXXX
1 or 31XXXX
The “correct” color values to use in high-resolution graphics ;-)

I would have needed to keep this chart nearby for reference until I memorized it.

What color values did you learn to use when you learned Extended Color BASIC? Leave a comment and let me know.

Until next time…

Bonus Code

Here’s my sample program.

0 'COLORS.BAS
10 PMODE 3,1:PCLS:SCREEN 1,0
20 GOSUB 500
30 PMODE 3,1:PCLS:SCREEN 1,1
40 GOSUB 500
50 PMODE 4,1:PCLS:SCREEN 1,0
60 GOSUB 500
70 PMODE 4,1:PCLS:SCREEN 1,1
80 GOSUB 500

499 END

500 ' SHOW COLORS
505 DRAW"BM10,3 D8R8U8NL8 BR20 ND8 BR28 R8D4L8D4R8 BR20 R8U4NL8U4NL8 BR20 D4R8NU4D4 BR20 R8U4L8U4R8 BR20 NR8D8R8U4NL8BU4 BR20 R8D8 BR20 R8U8L8D4R8"
510 FOR C=0 TO 8
520 COLOR C
530 LINE (C*28,16)-(C*28+27,191),PSET,BF
540 NEXT
550 IF INKEY$="" THEN 550
560 RETURN

Let’s write Lights Out in BASIC – part 2

See also: part 1, part 2, part 3, part 4, part 5, part 6 and part 7.

Updates:

  • 2023-02-06 – William Astle pointed out that Color BASIC doeshave ELSE. Not sure why I thought it didn’t — I never had a machine with plain Color BASIC. Striked out!

In the first installment, I shared a brief history of the game Lights Out using “extensive” research from the Wikipedia page and some YouTube videos.

This time, let’s look begin implementing the game in BASIC. My first goal is to write something generic enough that it could be easily ported to other systems. I specifically have VIC-20 in mind, since it was my first home computer.

After this is achieved, maybe we can see how much we could optimize and enhance it specifically for the CoCo (or VIC).

In Rick Adams‘ CoCo 3 version, he uses what appears to be the high-resolution 320×200 16-color graphics screen. It uses a joystick to move around and select squares.

Rick Adams’ Lights Out for CoCo 3.

It is quite nice, and reminds me of how his Shanghai game was controlled. (Rick wrote the official Color Computer version, sold on a ROM-Pak cartridge by Radio Shack.)

For my version, I’ll only use the text screen, and the keyboard to select squares.

Representing the Grid of Lights

Since the game is played on a 5×5 grid, a simple (and obvious) way to represent that grid of lights might be to use a two-dimensioned array. Something like this:

DIM L(4,4)

That may look wrong for a 5×5 grid, but on Color BASIC, dimensions start at 0. DIM X(4) gives entries X(0), X(1), X(2), X(3) and X(4). For DIM L(4,4) we get:

+---+---+---+---+---+---+
| . | 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+---+
| 0 | . | . | . | . | . |
+---+---+---+---+---+---+
| 1 | . | . | . | . | . |
+---+---+---+---+---+---+
| 2 | . | . | . | . | . |
+---+---+---+---+---+---+
| 3 | . | . | . | . | . |
+---+---+---+---+---+---+
| 4 | . | . | . | . | . |
+---+---+---+---+---+---+

If I were to do L(0,0)=123, the top left square would be 123:

+---+---+---+---+---+---+
| . | 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+---+
| 0 |123| . | . | . | . |
+---+---+---+---+---+---+
| 1 | . | . | . | . | . |
+---+---+---+---+---+---+
| 2 | . | . | . | . | . |
+---+---+---+---+---+---+
| 3 | . | . | . | . | . |
+---+---+---+---+---+---+
| 4 | . | . | . | . | . |
+---+---+---+---+---+---+

Then if I did L(3,2)=456:

+---+---+---+---+---+---+
| . | 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+---+
| 0 |123| . | . | . | . |
+---+---+---+---+---+---+
| 1 | . | . | . | . | . |
+---+---+---+---+---+---+
| 2 | . | . | . |456| . |
+---+---+---+---+---+---+
| 3 | . | . | . | . | . |
+---+---+---+---+---+---+
| 4 | . | . | . | . | . |
+---+---+---+---+---+---+

Toggling a Grid Value

By having a two-dimensional 5×5 array like that, I can represent the 25 squares of the Lights Out game. If I made it so a value of 0 was “off” and a value of “1” was on, I could toggle the value of a square using some simple logic like this:

IF L(X,Y)=1 THEN L(X,Y)=0 ELSE IF L(X,Y)=0 THEN L(X,Y)=1

Or, since I know I am only going to be putting a 0 or 1 there, I could simplify:

IF L(X,Y)=1 THEN L(X,Y)=0 ELSE L(X,Y)=1

That’s a bit clunky, and requires a BASIC that has the ELSE keyword. While the CoCo got ELSE with Extended BASIC, it was not present on the original Color BASIC. (Thanks, William A.!) My Commodore VIC-20 does not have it. To avoid using ELSE, it could be written like this:

100 IF L(X,Y)=1 THEN L(X,Y)=0:GOTO 120
110 L(X,Y)=1
120 ...program continues...

That “GOTO 120” to skip the next line is very important, else the first line would set it to 0, then the next line would set it back to 1. See? Clunky.

Since our goal is simply to toggle a square from on to off, or from off to on, the value is not important. It could be any two values, such as -57 and +123, using that code.

BUT, we can do better. We can make use of the BASIC mathematical NOT keyword. NOT is available in 1980 Color BASIC and even on the VIC-20.

NOT can be used on a number to flip it back and forth between two values:

PRINT NOT 0
-1

PRINT NOT -1
0

If we made 0 mean OFF, and -1 mean ON, we could toggle them back and forth by using NOT.

100 IF L(X,Y)=NOT L(X,Y)

That looks much simpler. And, as an added bonus, when you compare things in BASIC, the result is either -1 for TRUE, or 0 for FALSE. This is what the IF keyword is expecting. For example:

IF -1 THEN PRINT "THIS IS TRUE"

IF 0 THEN PRINT "YOU WON'T SEE THIS"

That will print “THIS IS TRUE”.

This would allow printing something quite easily based on the variable. We could use a FOR/NEXT loop for each row of the grid, and a second FOR/NEXT loop for each column in that row. A simple check could be done to decide if an “X” or “Y” should be printed for that grid element.

1000 REM SHOW GRID
1010 FOR Y=0 TO 4
1020 FOR X=0 TO 4
1030 IF L(X,Y) THEN PRINT "X";:GOTO 1050
1040 PRINT ".";
1050 NEXT
1060 PRINT
1070 NEXT
1080 PRINT

Since 0 represents FALSE (light is on), and since BASIC variables are initialized to 0, running that program should present a grid of all lights off (represented by a dot):

.....
.....
.....
.....
.....

If we set some of those array elements to -1 (FALSE, off), like this:

10 L(0,0)=-1
20 L(1,1)=-1
30 L(2,2)=-1
40 L(3,3)=-1
50 L(4,4)=-1

…then running it would show something like this:

X....
.X...
..X..
...X.
....X

This gives us a very simple “show grid” subroutine.

Selecting a Square to Toggle

If we go really, really old school, we could use INPUT and ask the user to tell us which square to toggle by using X and Y coordinates.

2000 REM INPUT SQUARE
2010 INPUT "X (0-4)";X
2020 INPUT "Y (0-4)";Y

Or, both variables could be asked for at the same time using “INPUT X,Y” like this:

2000 REM INPUT SQUARE
2010 INPUT "X,Y (0-4,0-4)";X,Y

To make sure typing a number larger than the array size (like 5), or smaller (like -5), does not crash the program, we should add some error checking:

2000 REM INPUT SQUARE
2010 INPUT "X,Y (0-4,0-4)";X,Y
2020 IF X<0 OR X>4 OR Y<0 OR Y>4 THEN 2010

Do you remember when we were learning BASIC like this? I promise, we’ll make it less remedial later.

Toggling that Square

Once we know the X and Y for a square inside the array, we can toggle that square as shown earlier:

L(X,Y)=NOT L(X,Y)

If the square value was 0, it will become -1. If it was -1, it will become zero. NOT does the work for us.

But, the way Lights Out works is it not only toggles that square, but the ones above, below, left and right of it (if there is a square there). Our toggle routine should do all that for us — and it should also know when there is not a square above, below, left or right of it:

3000 REM TOGGLE SQUARES
3010 L(X,Y)=NOT L(X,Y)
3020 IF X>0 THEN L(X-1,Y)=NOT L(X-1,Y)
3030 IF X<4 THEN L(X+1,Y)=NOT L(X+1,Y)
3040 IF Y>0 THEN L(X,Y-1)=NOT L(X,Y-1)
3050 IF Y<4 THEN L(X,Y+1)=NOT L(X,Y+1)

Let’s walk through that…

  • Line 3010 – toggles the selected square.
  • Line 3020 – if the selected square’s column (X) is greater than 0 (1-4), there will be a square to the left. Toggle that square (X-1).
  • Line 3030 – if the selected square’s column (X) is less than 4 (0-3), there will be a square to the right. Toggle that square (X+1).
  • Line 3040 – if the selected square’s row (Y) is greater than 0 (1-4), there will be a square above it. Toggle that square (Y-1).
  • Line 3050 – if the selected square’s row (Y) is less than 4 (0-3), there will be a square below it. Toggle that square (Y+1).

Putting it all together…

By adding a “RETURN” at the end of those three blocks of code, we can make them subroutines and call them using GOSUB. We now have the basic framework for a Lights Out game!

10 REM SHOW GRID
20 GOSUB 1000
30 REM INPUT SQUARE
40 GOSUB 2000
50 REM TOGGLE SQUARES
60 GOSUB 3000
70 REM REPEAT
80 GOTO 10

1000 REM SHOW GRID
1010 FOR Y=0 TO 4
1020 FOR X=0 TO 4
1030 IF L(X,Y) THEN PRINT ".";:GOTO 1050
1040 PRINT "X";
1050 NEXT
1060 PRINT
1070 NEXT
1080 PRINT
1090 RETURN

2000 REM INPUT SQUARE
2010 INPUT "X,Y (0-4,0-4)";X,Y
2020 IF X<0 OR X>4 OR Y<0 OR Y>4 THEN 2010
2030 RETURN

3000 REM TOGGLE SQUARES
3010 L(X,Y)=NOT L(X,Y)
3020 IF X>0 THEN L(X-1,Y)=NOT L(X-1,Y)
3030 IF X<4 THEN L(X+1,Y)=NOT L(X+1,Y)
3040 IF Y>0 THEN L(X,Y-1)=NOT L(X,Y-1)
3050 IF Y<4 THEN L(X,Y+1)=NOT L(X,Y+1)
3060 RETURN

BUT, since variables initialize as 0, and see means FALSE (off), there would be no lights on at the start of this game. The game would initialize to “already won” ;-) There would need to be some kind of initializing routine that sets some or all of the squares “on” at the start of the game.

But even with that, this would still be an un-win-able game – there is no code that checks to see if all the lights have been turned off.

Let’s add that in the next installment…

Displaying all 11 of the CoCo’s 8 colors…

I was today years old when I learned that the colors of the CoCo’s high resolution graphics screens are the same as the colors of the text mode semigraphics.

I knew that the CoCo’s MC6847 video chip could produce eight colors on the text screen. The manual describes them as green, yellow, blue, red, buff, cyan, magenta and orange. (Okay fine. It is really nine since you have black as well.)

These eight colors are shown in an example program in the Radio Shack quick reference guide. You will notice this does not draw a black strip for the 9th color – I guess theblack border is enough of a color test for black.

Color Adjustment Test Display, Radio Shack TRS-80 Color Computer Quick Reference Guide, page 55.

On the text screen, these colors are part of the character set. Each character block can have colors set in a 2X2 grid, with one color plus black per character location.

I also knew that when you went in to one of the 4-color high resolution graphics modes, PMODE 1 or PMODE 3, you had two sets of colors available.

In SCREEN 1,0, you get a green border, and four colors – green, yellow, blue and red.

In SCREEN 1,1, you get a white border and four colors – white, green, purple and orange.

I wondered if it might be possible to write some code to switch graphics modes and get all of these colors on screen at the same time. I created a sample of what it might look like … and then I realized these colors are all the same!

For SCREEN 1,0 you are getting the same green, yellow, blue and red that the text screen has.

For SCREEN 1,1 you are getting the same buff, cyan, magenta and orange that the text screen has.

“I feel dumb I never realized they were the same colors!”

– Allen

Here is the program I used to switch between them to get my screen shots…

0 'ALL COCO 1/2 COLORS

10 CLS0:PRINT@4*32,;
20 FOR R=0 TO 3
30 FOR C=0 TO 3
40 PRINT STRING$(8,143+C*16);
50 NEXT:NEXT
60 FOR R=0 TO 3
70 FOR C=4 TO 7
80 PRINT STRING$(8,143+C*16);
90 NEXT:NEXT
95 GOSUB 1000

100 ' COLOR SET 0
110 PMODE 1,1:PCLS:SCREEN 1,0
120 FOR C=1 TO 3
130 COLOR C:LINE((C-1)*64,0)-((C-1)*64+63,0+47),PSET,BF
140 NEXT
145 COLOR 0:LINE(3*64,0)-(3*64+63,0+47),PSET,BF
150 GOSUB 1000

200 ' COLOR SET 1
210 PMODE 1,1:PCLS:SCREEN 1,1
220 FOR C=1 TO 3
230 COLOR C:LINE((C-1)*64,144)-((C-1)*64+63,144+47),PSET,BF
240 NEXT
245 COLOR 0:LINE(3*64,144)-(3*64+63,144+47),PSET,BF
250 GOSUB 1000

999 END

1000 IF INKEY$="" THEN 1000
1010 RETURN

This means, even with the two different graphics mode color sets, you still only get those eight (or nine, including black) colors to play with.

BUT… technically there are more color than that. The color of the text characters is not black — but some kind of dark green (see the square I drew to the left of the text, below):

And, there is an alternate color set for the text screen that has a different color for the text, and a different color for the background.

Or does it?

Admittedly, the usefulness of the text colors is limited since you cannot do anything with those colors except put text characters on the screen with them… (More on this in a moment…)

Having the alternate background does seem useful. Or is it?

I was today years old when I learned that the alternate background text color (SCREEN 0,1) is the same as one the orange primary color (CHR$ 255), just as the normal background text color (SCREEN 0,0) is the same as the green primary color (CHR$ 143)!

Sample code:

10 CLS
20 PRINT "----SPACES-----";CHR$(128);CHR$(128)"---CHR$(143)---";
30 FOR R=1 TO 14
40 PRINT STRING$(15," ");STRING$(2,128);STRING$(15,143);
50 NEXT
60 PRINT "----SPACES-----";CHR$(128);CHR$(128)"---CHR$(143)--";
70 IF INKEY$="" THEN 70

80 CLS
90 PRINT "----SPACES-----";CHR$(128);CHR$(128)"---CHR$(255)---";
100 FOR R=1 TO 14
110 PRINT STRING$(15," ");STRING$(2,128);STRING$(15,255);
120 NEXT
130 PRINT "----SPACES-----";CHR$(128);CHR$(128)"---CHR$(255)--";
140 SCREEN 0,1

150 GOTO 70

So I guess that, even with the alternate color set, you still only have the same eight colors plus black – plus whatever color the text is, which you cannot use.

Or can you?

Lowercase is represented by inverted video, and although you cannot PRINT a lowercase space, you can POKE it to the screen.

POKE 1024,32

That will poke the inverted space to the top left of the 32 column screen.

And that is another color!

Let’s update the color bar…

10 CLS
20 FOR R=0 TO 15
30 PRINT @R*32,"X";
40 FOR C=0 TO 7
50 PRINT STRING$(3,143+C*16);
60 NEXT
70 PRINT STRING$(3,128);
80 POKE 1024+32*R+28,32:POKE 1024+32*R+29,32:POKE 1024+32*R+30,32
90 POKE 1024+32*R+31,ASC("X")
100 NEXT
110 IF INKEY$="" THEN 110
120 SCREEN 0,1
130 IF INKEY$="" THEN 130
140 SCREEN 0,0
150 GOTO 110

This program will print vertical bars of the 9 semigraphics block colors – black, green, yellow, blue, red, buff, cyan, magenta and orange.

It then uses POKE to set three blocks on each line to an inverted space (“lowercase space”) to show that color. The end result is ten colors on the screen:

Look closely on the right — there is black bar, then a bar using the text color (inverted space), then the bar of Xs.

Pressing a key flips to the alternate color mode and that helps make that last column easier to see:

This means if you wanted to do glorious 32×16 color graphics, you actually have 11 colors you can choose from, though that would be the ten at a time (nine base colors plus the text color of the mode).

But I expect many of you already knew this.

Let’s write Lights Out in BASIC – part 1

See also: part 1, part 2, part 3, part 4, part 5, part 6 and part 7.

Recently, Rick Adams let me see a CoCo 3 Lights Out game he was working on. I have heard of the Lights Out, but have never played it. I gave it a shot…

I was immediately frustrated by how difficult such a simple game could be to win. In fact, I have yet to purposely win it, but I did get lucky one time and accidentally won.

For those who, like I was, are unfamiliar with the game… There is a 5×5 grid of squares. Of the 25 squares, random squares will be “on”, represented as green in Rick’s version. The goal is to turn them all off, represented by black.

You select a square, and that square, and the squares above, below, left and right of it will switch their state. If an adjacent square is on, it will be turned off. If it is off, it will be turned on. If you are at the edge of the grid, it does not wrap around and affect any squares on the other side.

Simple… and incredibly frustrating. I can manage to get down to one or two squares, but still haven’t figured out a pattern to shut them all off. It reminds me of when I was trying to figure out a Rubik’s Cube when they were new (maybe around 1979 or 1980?). I never did. I gave up the first week and ordered the official solution manual.

I recall Lights Out being quite trendy in recent years — maybe as a phone app or something online. This made me wonder about the origin of the game. I decided to do some “intensive/extensive” research.

1990s

From checking the always accurate and reliable Wikipedia, I learned that a game called “Lights Out” first appeared in 1995 as a handheld electronic game from Tiger Electronics. That version used a 5×5 grid of push button lights. Here is a commercial for it:

Lights Out (1995) TV commercial.

From that TV ad, I learned that not only was there the 5×5 original, but also a “Deluxe Lights Out” that used a 6×6 grid.

In 1997 they also released Lights Out in cartridge form for their touchscreen Game.com game system. I owned one of those, and since I read this game was included with the system, perhaps I did play it back then. From looking at a gameplay video, this version appears to use a 6×6 grid of lights, which I suppose made it closer to Deluxe Lights Out.

Side note: I believe it was the late Steve Bjork that told me about Game.com. It had the potential to be a Gameboy Killer, but disappeared into obscurity instead. I had one and a number of the cartridges. I actually found my Game.com Monopoly cartridge a few weeks ago, but I sold the game unit years ago.

But I digress…

1980s

Tiger Electronics was not the first to sell this game — only the first (that I can find) to call it Lights Out. In 1983, there was a handheld game called XL25 from Vulcan Electronics . It appears to play the same style game — except the goal was to turn all the lights ON instead of off… Did Tiger rip them off, 12 years later? (And what does XL25 even mean?)

XL25 TV commercial.

I can find very little about this game, and even less about Vulcan Electronics. Please comment if you can find more information.

1970s

The Wiki also mentions a similar game existed in the 1970s for the Parker Brothers Merlin handheld system. I remember seeing TV ads for Merlin, and I recall wanting one. I don’t think I ever even got to play with one, though.

From this TV ad, the game in question appears to be Magic Square. The goal of it was not to get all of its 3×3 lights off or on, but to make just the outer lights on to form a square.

It does appear the game mechanics where the same as Lights Out.

Did Magic Square lead to XL25 which led to Lights Out? Or was there something even earlier? Maybe on some mainframe system? Leave a comment if you have more information on just what “Lights Out” patient zero is.

Present Day (not Christmas or Birthday)

Since the concept was known in the 1970s, someone could have used it for inspiration to write a CoCo version of the Merlin 3×3 “Magic Square” on a 1980 CoCo. In 1983, a CoCo owner could have created a 5×5 XL25 version. Heck, many of us were still using our CoCos in 1995 and 1997 when Tiger Electronics had their 5×5 and 6×6 versions.

Did you ever see this game on the CoCo back then?

Inspired by Rick Adams’ work, I thought it might be fun to see how much effort this game would be to write. I expect it will be much easier to write than it is to win.

In the next installment, we’ll look at some ways to implement this game in Color BASIC.

Until then…

How much faster is HEX versus decimal on the CoCo?

This is a topic I have mentioned in earlier articles about speeding up BASIC. I recently found one of my test programs and thought I’d update it a bit and share it.

A quick recap…

In BASIC, numbers in the program are stored as the characters. If you have “A=123” that “123” appears in the BASIC code as those characters. When the program RUNs, basic has to convert that series of characters to a number.

It takes more work to parse a standard base-10 (decimal, digits 0-9) set of characters to a number than it does to parse a base-16 (HEX, digits 0-F). To demonstrate, I wrote a very simple parser. It takes a string and converts it to a number, manually. (BASIC already has a VAL keyword that does this, but I wanted to show how it works.) Note this does not look for negative (“-“) or decimals or scientific notation – just a basic number like “12345”.

Decimal String to Number

10 ' STRTONUM.BAS
20 LINE INPUT "TYPE A NUMBER: ";NM$
30 GOSUB 60
40 PRINT "THE VALUE IS :";NM
50 END
60 ' CONVERT NM$ TO NM NUMBER
70 NM=0:ZM=1
80 ' SCAN FROM RIGHT TO LEFT
90 FOR Z=LEN(NM$) TO 1 STEP -1
100 ' GET CHARACTER VALUE
110 ZC=ASC(MID$(NM$,Z,1))
120 ' EXIT IF NOT 0-9
130 IF ZC>=ASC("0") THEN IF ZC<=ASC("9") THEN 160
140 PRINT "NOT A NUMBER : ";NM$
150 RETURN
160 ' SUBTRACT ASCII "0" AND MATH
170 NM=NM+(ZC-ASC("0"))*ZM
175 PRINT ZC-ASC("0"); "*";ZM;"=";NM
180 ' 0, 10, 100, 1000, ETC.
190 ZM=ZM*10
200 NEXT
210 RETURN

If you have a number like “12345”, you start at the right-most ASCII character (“5”) and convert that to a number. You multiply that number by a multiplier that starts out as 1. So, “5 * 1 = 5”.

Then you multiply the multiplier by 10, so 1 becomes 1. You move to the next digit, “4”, and multiply it by the new multiplier. So, “4*10 = 40”. That is added to the previous value, so “5 + 40 = 45”.

The multiplier is multiplied by 10, so 10 becomes 100. The next digit is a “3”, so that becomes “3 * 100 = 300”. It is added to the sum – “300 + 45 = 345”.

Repeating, the multiplier is multiplied by 10 making it 1000. The next digit is a “2”, so that becomes “2 * 1000 = 2000”. That is added making “2000 + 345 = 2345”. I think we see the pattern.

After the multiplier is multiplied by 10 again, making it 10000, we go through this again with the final digit, the “1”. That makes “1 * 10000 = 10000” and that is added making “10000 + 2345 = 12345”.

Whew!

HEX String to Value

But, with a hexadecimal value, the math gets much simpler since each character of a hex string represents a set of four bits in a byte. A similar converter is much smaller.

10 ' STRTONUM.BAS
20 LINE INPUT "TYPE A HEXNUM: ";NM$
30 GOSUB 60
40 PRINT "THE VALUE IS :";NM
50 END
60 ' CONVERT NM$ TO NM NUMBER
70 NM=0
80 ' SCAN FROM LEFT TO RIGHT
90 FOR Z=1 TO LEN(NM$)
100 ' GET CHARACTER VALUE
110 ZC=ASC(MID$(NM$,Z,1))
120 ' EXIT IF NOT 0-9 OR A-F
130 IF ZC>=ASC("0") THEN IF ZC<=ASC("9") THEN 200
140 IF ZC>=ASC("A") THEN IF ZC<=ASC("F") THEN 180
150 PRINT "NOT A HEXNUM : ";NM$
160 RETURN
170 ' CONVERT A-F TO 10-15
180 ZC=ZC-(ASC("A")-(ASC("9")+1))
190 ' NOW MAKE 0-15
200 ZC=ZC-ASC("0")
210 PRINT NM;"+";ZC;"=";
220 NM=NM+ZC
230 PRINT NM
240 IF Z<LEN(NM$) THEN NM=NM*16
250 NEXT
260 RETURN

In BASIC, once it sees some characters starting with “&H”, it gets the value of the next character. If it is A-F, it subtracts from the value so it looks like the ASCII values after “0” to “9”.

Then it subtracts the ASCII of “0” so the value becomes 0-15.

If there is another character, it shifts this value four places to the left (multiply by 16 in the code above) and it moves on to the next digit and repeats.

Bit shifts (multiplying by power of 2) are much quicker than multiplying. It makes the whole parsing routine much faster.

But how much faster?

I wrote this sample program which sits in a loop and sets a variable 10,000 times — first setting using a normal base-10 number (“A=1”), and then again using the HEX version (“A=&H1”). After each one it prints the TIMER value, and at the end of the line it prints how much faster (or slower) the HEX version was over decimal.

And as a bonus, at the end, it compares “A=.” (that is a fast shortcut for “A=0”) to “A=&H0” to show one case where there is something faster than HEX.

10 'DECVSHEX2.BAS
20 DIM A,I,TD,TH:MX=10000

30 PRINT "DO NOT PRESS KEYS WHILE RUNNING"
40 FOR I=1 TO 1000:NEXT I

50 PRINT "DEC TIME HEX TIME DIFF"

60 TIMER=0:FOR I=1 TO MX
70 A=0
80 NEXT:TD=TIMER:GOSUB 920
90 TIMER=0:FOR I=1 TO MX
100 A=&H0
110 NEXT:TH=TIMER:GOSUB 930

120 TIMER=0:FOR I=1 TO MX
130 A=1
140 NEXT:TD=TIMER:GOSUB 920
150 TIMER=0:FOR I=1 TO MX
160 A=&H1
170 NEXT:TH=TIMER:GOSUB 930

180 TIMER=0:FOR I=1 TO MX
190 A=2
200 NEXT:TD=TIMER:GOSUB 920
210 TIMER=0:FOR I=1 TO MX
220 A=&H2
230 NEXT:TH=TIMER:GOSUB 930

240 TIMER=0:FOR I=1 TO MX
250 A=3
260 NEXT:TD=TIMER:GOSUB 920
270 TIMER=0:FOR I=1 TO MX
280 A=&H3
290 NEXT:TH=TIMER:GOSUB 930

300 TIMER=0:FOR I=1 TO MX
310 A=4
320 NEXT:TD=TIMER:GOSUB 920
330 TIMER=0:FOR I=1 TO MX
340 A=&H4
350 NEXT:TH=TIMER:GOSUB 930

360 TIMER=0:FOR I=1 TO MX
370 A=5
380 NEXT:TD=TIMER:GOSUB 920
390 TIMER=0:FOR I=1 TO MX
400 A=&H5
410 NEXT:TH=TIMER:GOSUB 930

420 TIMER=0:FOR I=1 TO MX
430 A=6
440 NEXT:TD=TIMER:GOSUB 920
450 TIMER=0:FOR I=1 TO MX
460 A=&H6
470 NEXT:TH=TIMER:GOSUB 930

480 TIMER=0:FOR I=1 TO MX
490 A=7
500 NEXT:TD=TIMER:GOSUB 920
510 TIMER=0:FOR I=1 TO MX
520 A=&H7
530 NEXT:TH=TIMER:GOSUB 930

540 TIMER=0:FOR I=1 TO MX
550 A=8
560 NEXT:TD=TIMER:GOSUB 920
570 TIMER=0:FOR I=1 TO MX
580 A=&H8
590 NEXT:TH=TIMER:GOSUB 930

600 TIMER=0:FOR I=1 TO MX
610 A=9
620 NEXT:TD=TIMER:GOSUB 920
630 TIMER=0:FOR I=1 TO MX
640 A=&H9
650 NEXT:TH=TIMER:GOSUB 930

660 TIMER=0:FOR I=1 TO MX
670 A=10
680 NEXT:TD=TIMER:GOSUB 920
690 TIMER=0:FOR I=1 TO MX
700 A=&HA
710 NEXT:TH=TIMER:GOSUB 930

720 TIMER=0:FOR I=1 TO MX
730 A=11
740 NEXT:TD=TIMER:GOSUB 920
750 TIMER=0:FOR I=1 TO MX
760 A=&HB
770 NEXT:TH=TIMER:GOSUB 930

780 GOTO 850

790 TIMER=0:FOR I=1 TO MX
800 A=12
810 NEXT:TD=TIMER:GOSUB 920
820 TIMER=0:FOR I=1 TO MX
830 A=&HC
840 NEXT:TH=TIMER:GOSUB 930

850 TIMER=0:FOR I=1 TO MX
860 A=.
870 NEXT:TD=TIMER:PRINT " . ";:PRINT USING"#####";TD;:PRINT" ";
880 TIMER=0:FOR I=1 TO MX
890 A=&H0
900 NEXT:TH=TIMER:GOSUB 930

910 GOTO 910

920 PRINT USING"### ##### ";A;TD;:PRINT" ";:RETURN

930 PRINT "&H";HEX$(A);" ";:PRINT USING"##### ";TH;:PRINT USING "###.##%";((TD-TH)/TD)*100:RETURN

Running this program (eventually) displays:

So the answer is — for zero, 7% faster. For other single digit values, only slightly faster. For multiple digit values, about 30% faster. BUT, if using zero, using the period (“A=.”) will be about 16% faster than using HEX.

Thank you for coming to my talk.

Until next time…

1986 Doctor Who demo source found.

As I wrote about earlier, in 1986 I created a demo program that displays a Doctor Who logo (based on the one from the Tom Baker era of the show) and played a version of the theme song I created in Musica 2.

Doctor Who music demo.

You can download a disk image of this demo from the CoCo archive site:

https://colorcomputerarchive.com/repo/Disks/Demos/Dr.%20Who%20Demo%20%28Allen%20Huffman%29.zip

I created the music by ear (listening to a cassette tape recording I made from TV) in Musica 2:

Here is a video of the demo playing:

I remembered using a BASIC program to draw most of the logo, then using some graphics program to add the text. I have recently located the original BASIC program:

10 PMODE4,1:COLOR0,1:PCLS:SCREEN1,1
15 GOTO30
20 DRAW"BM128,20;M35,90;M128,160;M220,90;M128,20;BM128,30;M47,90;M128,150;M208,90;M128,30"
25 GOTO25
30 CIRCLE(128,135),100,,1,.66,.85:CIRCLE(128,135),80,,1,.66,.85:LINE(73,53)-(83,68),PSET:LINE(182,53)-(172,68),PSET:PAINT(128,36)
40 DRAW"BM65,70;M70,110;M80,110;M85,95;M90,110;M100,110;M105,70;M95,70;M93,95;M85,80;M78,95;M78,95;M75,70;M65,70":PAINT(66,71)
50 DRAW"BM110,70;M110,110;M120,110;M120,95;M140,95;M140,110;M150,110;M150,70;M140,70;M140,85;M120,85;M120,70;M110,70":PAINT(111,71)
60 CIRCLE(175,90),21:CIRCLE(175,90),12:PAINT(175,71)
70 GOTO20

It draws this:

Sometime, I’d like to try to create a more accurate version of that logo, and update the music to be more accurate as well.

Sometime.

Getting LN in BASIC on a machine that only has LOG

I need to know the real way to do this. BING AI and ChatGPT keep giving me different solutions, and only this last one works. Or seems to work.

I was amused that the BING AI suggested using DEF FN to create this function on a BASIC without LN.

DEF FNLN(x)
=LOG(x) / LOG(2.71828)

Changing the X to uppercase allows this to work on the CoCo. The results are close — are they close enough? Would more decimal places in the LOG value help?

Where are the math people?

PUT defined by ASCII strings

NOTE: Can anyone tell me how to get the blank lines out of the code listings? I used to be able to copy/paste from MS Visual Studio Code with no problem, but something has changed in WordPress. For the past few weeks, I have to paste in (it looks fine), then when I look at it, it has the line feeds. I then EDIT, and copy/paste it back in to Code (where I see the blank lines) then search/replace those blank lines, then copy/paste it back in to WordPress. That has been working fine, but now that does not work. Maybe it’s a different between PC Code and Mac Code (PC using CR/LF or something?). Anyone know?

Revisiting the PUT from DATA concept… For those who don’t want to figure out the binary values for the characters, here is a routine that lets you define them using strings:

'TANK UP
DATA " XX "
DATA " XX "
DATA "XX XX XX"
DATA "XXXXXXXX"
DATA "XXXXXXXX"
DATA "XXXXXXXX"
DATA "XXXXXXXX"
DATA "XX XX"

The routine reads these 8-character strings, then goes through them to build a value based on where the X is found.

Here is some code you can play with…

0 'PUTDATA.BAS
1 '2024-01-22
2 'SHOWS HOW TO DO IT USING
3 'STRINGS RATHER THAN #S
4 '

10 'TO SPEED UP STR-TO-BYTE
20 DIM BT(7):FOR BT=0 TO 7:BT(BT)=2^BT:NEXT
30 '
40 'VARIABLES USED IN THE
50 'POKE-TO-ARRAY ROUTINE MUST
60 'BE PRE-ALLOCATED OR THEY
70 'WILL CAUSE ARRAY MEM TO
80 'SHIFT WHEN IT GET USED.
90 '
100 DIM L,V,Z,Z$
110 '
120 'EACH ARRAY ENTRY CAN STORE
130 '5 BYTES. AN 8X8 SINGLE
140 'COLOR CHARACTER IS 8, SO
150 'WE NEED TWO ARRAY ENTRIES
160 '(10 BYTES) TO FIT THE 8
170 'BYTE CHARACTER.
180 '
190 DIM TU(1),TD(1),TL(1),TR(1):GOSUB 320

200 '
210 ' TEST PROGRAM
220 '
230 PMODE 4,1:PCLS 1:SCREEN 1,1
240 PUT (0,0)-(7,7),TU
250 PUT (16,0)-(16+7,7),TD
260 PUT (32,0)-(32+7,7),TL
270 PUT (48,0)-(48+7,7),TR
280 GOTO 280

290 '
300 'LOAD SPRITE CHARACTERS
310 '
320 PRINT "LOADING DATA";
330 L=VARPTR(TU(0)):GOSUB 390
340 L=VARPTR(TD(0)):GOSUB 390
350 L=VARPTR(TL(0)):GOSUB 390
360 L=VARPTR(TR(0)):GOSUB 390
370 RETURN

380 '
390 'READ DATA AND POKE AT L
400 '
410 PRINT
420 'READ STRINGS AND CONVERT
430 'TO BYTES.
440 FOR Z=0 TO 7:V=0
450 READ Z$:PRINT Z$,;
460 FOR BT=1 TO 8
470 'FASTER WAY
480 IF MID$(Z$,BT,1)="X" THEN V=V+BT(BT-1)
490 'SLOW WAY
500 'IF MID$(Z$,BT,1)="X" THEN V=V+2^(BT-1)
510 NEXT:PRINT INT(V);HEX$(V)
520 POKE L+Z,(NOT V)+256:NEXT:RETURN
530 NEXT:PRINT V;HEX$(V):NEXT
540 RETURN

550 '
560 '8X8 SPRITE CHARACTERS
570 '
580 'TANK UP
590 DATA " XX "
600 DATA " XX "
610 DATA "XX XX XX"
620 DATA "XXXXXXXX"
630 DATA "XXXXXXXX"
640 DATA "XXXXXXXX"
650 DATA "XXXXXXXX"
660 DATA "XX XX"

670 'TANK DOWN
680 DATA "XX XX"
690 DATA "XXXXXXXX"
700 DATA "XXXXXXXX"
710 DATA "XXXXXXXX"
720 DATA "XXXXXXXX"
730 DATA "XX XX XX"
740 DATA " XX "
750 DATA " XX "

760 'TANK LEFT
770 DATA " XXXXXX"
780 DATA " XXXXXX"
790 DATA " XXXX "
800 DATA "XXXXXXX "
810 DATA "XXXXXXX "
820 DATA " XXXX "
830 DATA " XXXXXX"
840 DATA " XXXXXX"

850 'TANK RIGHT
860 DATA "XXXXXX "
870 DATA "XXXXXX "
880 DATA " XXXX "
890 DATA " XXXXXXX"
900 DATA " XXXXXXX"
910 DATA " XXXX "
920 DATA "XXXXXX "
930 DATA "XXXXXX "

You can take this and change the characters real easily to play with it. Here is a smiling face instead of the UP TANK:

580 'SMILING FACE
590 DATA " XXXXXX "
600 DATA "X X"
610 DATA "X X X X"
620 DATA "X X"
630 DATA "X X X X"
640 DATA "X XX X"
650 DATA " X X "
660 DATA " XXXX "

Have fun… When I get time, I’ll try to post versions of these routines on my Github that handle different size objects as well as 4-color objects for us on PMODE 1 and 4 screens.

Tank 8×8 with no flicker, tracks and sound.

When I posted a video of my CoCo Factory TNT test, Chet Simpson suggested I could eliminated flicker by making a double-high sprite, with the top half blank. When I put the falling bomb, it would erase the position after it. L. Curtis Boyle suggested something similar to my tank game.

So I did it. It took a bit to figure out the logic. I have four 8×8 characters of the tank facing each direction, then I have two 16×8 (for left, and right) and two 8×16 (for up and down) versions.

Ericomont mentioned that the tank could leave tracks (I guess, since it seems like my black on white screen looks like snow). I added those too.

And then some sound. When the tank is not moving, the sound is slow — as if the tank is idling. When the taking is moving, it makes a faster sound.

I am having fun playing.

This version does to have the firing. I need to optimize this a bit and then add some bullets to it ;-)

Here is a video:

And here is the current code. There are some commented out lines I was using for debugging – like making a box around where the tank’s current position is (TX/TY) and where the old position was (OX/OY). That was massively helpful in me being able to see the logic to how I should draw and erase the tanks.

Now that I understand it, maybe I can do it better.

And this code can certainly be optimized and be made much faster.

Enjoy…

0 ' 
1 ' TANKPUT8X8-SOUND.BAS
2 ' ALLEN C. HUFFMAN
3 ' SUBETHASOFTWARE.COM
4 ' 2023-01-19
5 '

10 ' LOAD SPRITES
20 DIM TU(1),TD(1),TL(1),TR(1),UE(4),DE(4),LE(4),RE(4),Z,L,V:GOSUB 2000

30 ' ARROW KEYS
40 KY$=CHR$(94)+CHR$(10)+CHR$(8)+CHR$(9)

50 ' 256X192 BLACK AND WHITE
60 PMODE 4,1:PCLS 1:SCREEN 1,1

70 ' TANK POSITION AND DIR.
80 TX=8:TY=8:TD=4:OX=8:OY=8:Z=0

90 ' ERASE PREV POSITION
100 LINE(OX,OY)-(OX+7,OY+7),PSET,BF
110 ' PUT TANK ON SCREEN
130 PUT(TX,TY)-(TX+7,TY+7),TU:GOTO 180
140 PUT(TX,TY)-(TX+7,TY+7),TD:GOTO 180
150 PUT(TX,TY)-(TX+7,TY+7),TL:GOTO 180
160 PUT(TX,TY)-(TX+7,TY+7),TR:GOTO 180
165 ' PUT WITH BLANK NEXT TO IT
166 PUT(TX,TY)-(TX+7, TY+15),UE:GOTO 180
167 PUT(OX,OY)-(OX+7, OY+15),DE:GOTO 180
168 PUT(TX,TY)-(TX+15,TY+7),LE:GOTO 180
169 PUT(OX,OY)-(OX+15,OY+7),RE

170 ' READ KEYBOARD (WASD)
180 Z=0:POKE&H155,&HFF:POKE&H156,&HFF:POKE&H157,&HFF:POKE&H158,&HFF
181 'LINE(TX-1,TY-1)-(TX+8,TY+8),PRESET,B
182 'LINE(OX-1,OY-1)-(OX+8,OY+8),PRESET
185 Z=Z-1:IF Z<0 THEN Z=20:EXEC 43345
190 A$=INKEY$:IF A$="" THEN 185
191 'LINE(TX-1,TY-1)-(TX+8,TY+8),PSET,B
192 'LINE(OX-1,OY-1)-(OX+8,OY+8),PSET
200 LN=INSTR(KY$,A$):IF LN=0 THEN 180
210 OX=TX:OY=TY
220 ON LN GOTO 240,270,300,330

230 ' UP
240 IF TD=1 THEN IF TY>0 THEN TY=TY-8:GOTO 166
250 TD=1:GOTO 130
260 ' DOWN
270 IF TD=2 THEN IF TY<184 THEN TY=TY+8:GOTO 167
280 TD=2:GOTO 140
290 ' LEFT
300 IF TD=3 THEN IF TX>0 THEN TX=TX-8:GOTO 168
310 TD=3:GOTO 150
320 ' RIGHT
330 IF TD=4 THEN IF TX<248 THEN TX=TX+8:GOTO 169
340 TD=4:GOTO 160

999 GOTO 999

2000 ' LOAD SPRITE CHARACTERS
2010 PRINT "LOADING DATA";
2030 L=VARPTR(TU(0)):GOSUB 3000
2040 L=VARPTR(TD(0)):GOSUB 3000
2050 L=VARPTR(TL(0)):GOSUB 3000
2060 L=VARPTR(TR(0)):GOSUB 3000
2170 ' 8X16 AND 16X8
2180 L=VARPTR(UE(0)):GOSUB 3025
2190 L=VARPTR(DE(0)):GOSUB 3025
2200 L=VARPTR(LE(0)):GOSUB 3025
2210 L=VARPTR(RE(0)):GOSUB 3025
2220 RETURN

3000 ' READ DATA AND POKE AT L
3010 PRINT ".";
3020 'FOR Z=L TO L+7:READ V:POKE Z,(NOT V)+256:NEXT:RETURN
3021 FOR Z=L TO L+7:READ V:POKE Z,(NOT V)+256:NEXT:RETURN
3025 PRINT "--";
3026 FOR Z=L TO L+15:READ V:POKE Z,(NOT V)+256:NEXT:RETURN
3030 ' 8X8 SPRITE CHARACTERS
3040 ' TANK UP
3050 DATA 24,24,219,255,255,255,255,195
3060 ' TANK DOWN
3070 DATA 195,255,255,255,255,219,24,24
3080 ' TANK LEFT
3090 DATA 63,63,30,254,254,30,63,63
3100 ' TANK RIGHT
3110 DATA 252,252,120,127,127,120,252,252

3120 ' TANK UP+EMPTY
3130 DATA 24,24,219,255,255,255,255,195
3131 DATA 0,195,0,0,0,195,0,0
3140 ' TANK EMPTY+DOWN
3150 DATA 0,0,195,0,0,0,195,0
3151 DATA 195,255,255,255,255,219,24,24
3160 ' TANK LEFT+EMPTY
3170 DATA 63,68, 63,68, 30,0, 254,0, 254,0, 30,0, 63,68, 63,68
3180 ' TANK EMPTY+RIGHT
3190 DATA 34,252, 34,252, 0,120, 0,127, 0,127, 0,120, 34,252, 34,252