Author Archives: Allen Huffman

About Allen Huffman

Co-founder of Sub-Etha Software.

My 1983 VIC-20 Eggs game has a typo in the joystick routine

Down the VIC-20 joystick rabbit hole I go…

In my recently-recovered “first program I ever had published,” I noticed that the joystick was not working. I was testing on VICE (the Versatile Commodore Emulator) on a Mac. The code that I had to read the joystick was clearly something I found in a magazine or somewhere because I have no idea what it does:

30 POKE37154,127
35 J=(NOT((PEEK(37151)AND128)/8+(PEEK(37151)AND60)/4))+32
40 POKE37154,255

I suspected maybe a typo was introduced when VIC-NIC NEWS typed in my program to print it out for publication. I did some searching to see how you were supposed to read the VIC-20 joystick. I was surprised that the Commodore VIC-20 manual didn’t offer any code to do this.

I found an Atari Magazine page that simply said you used two PEEKs:

The VIC is designed to handle only one joystick, and it takes two bytes to control that joystick. In the VIC, location 37137 is PEEKed to read the joystick for the up, down, left, and fire button movements. Location 37152 is PEEKed to detect movements to the right.

To see just how easy it is to detect movement on the joystick, plug in your joystick, type in one of the following short programs, and then RUN. The programs simply PEEK the joystick control bytes, and then PRINT that reading to the screen.

For the VIC-20:

10 PRINT PEEK(37137), PEEK(37152) : GOTO 10
– Atari Magazine, issue 42

Curious. My code was not using either of those addresses. Either my code or this magazine had a typo.

I tried those two PEEKs in VICE and noticed only the fire button was making the values change. This matched the VICE joystick display also showing only the fire button working.

I then thought the joystick I was using (a USB joystick that came with my TheVIC20) might have an issue. I tested it using a joystick test program, and it appeared to read all directions correctly.

A bit of more searching and I found that the Mac version of VICE has has an issue with joysticks not working since sometime in 2022:

https://sourceforge.net/p/vice-emu/bugs/1785

Even if my code was correct (to be determined), I would not be able to test it on the Mac version of VICE.

I then tried running Eggs from the Windows version of VICE and was able to see the joystick work — but, it was using UP and DOWN to move the cup left and right. Odd. I know I must have intended for it to use left and right, because my typed instructions clearly stated:

“Use joystick to move the cup left and right to catch falling eggs.”

– Eggs instructions.

While technically it didn’t say “move the joystick left or right,” I think it would have been a very odd choice for me to use “up” to mean left, and “down” to mean right, in a game like this.

This led me back to suspecting a typo in my joystick code. I went back to those two PEEKs from Atari magazine and tested them on the Windows version of VICE. This time, it seemed to change for all directions other than right. It gave values for Up, Up-Left, Left, Left-Down and Down, as well as the button. Clearly, this code was wrong (or maybe the Windows version of VICE also had an issue).

I decided to figure out where my joystick code came from. I searched for this code:

J=(NOT((PEEK(37151)AND128)/8+(PEEK(37151)AND60)/4))+32

…and archive.org actually had a single match! It was found in Issue #8 of The TORPET (Toronto Pet) on page 31. This Commodore PET publication had a section about the then-new VIC-20. For fun, here is the entirety of their VIC-20 section:

VIC NOTES
by John O’Hare

As of Mid October, 15,000 VIC’s have been sold in Japan, 15,000 more in the U.S., and, though not yet available in Europe, orders are accumulating fast. -JS

If you really want a color PET, Commodore suggests you consider buying a VIC as a peripheral for your PET! Seriously, it uses Upgrade BASIC V2, is cassette compatible, and has excellent color compared to Apple, and Atari. -JS

Some VIC POKE locations are:

51 decrements when key hit. 204 cursor on flag.
56 pointer to top of memory. 211 cursor column.
67 holds 1 when key hit. 214 cursor row.
197 value of key depressed. 36865 border position (vertical).
145 flag for left shift key. 36864 border position (horizontal).
245 detects special keys. 36869 pointer to character generator.
240= norm. 255 = 7168.

To read a joystick on a VIC (standard ATARI joystick works), use the following subroutine:

9000 POKE 37154,127
9010 JO= (NOT((PEEK(37152)AND128) /8+( PEEK(37151)AND60)/4)) +32
9020 POKE 37154,255
9030 RETURN

JO Values returned are: 1 = up, 17 = up and rt, 16= right, 18 = down and r t,
2 = down, 6 = down and Ift, 4= left, 5= up and Ift.

VIC GAME REVIEWS

VIC GAMES PAC, $25 from Creative Software. 3 VIC arcade games: VIC Trap, Seawolf, and Bounce Out. Seawolf and Bounce Out are machine language, with very fast action. Very good games, but could be better if they used Hi Res graphics. -JOH

– The TORPET, Issue #8, Page 31

Wow, early days – reporting only 15,000 VIC-20s had been sold at that point!

In my code, I check for the value of 18 to move the bucket left (“ifj=18thenb=b-1”) and a value of 17 to move the bucket right (“ifj=17thenb=b+1”). That matches the values for up and down in this TORPET article! I guess I really did mean for up and down to move left and right.

But I have a theory about this, which I will get to in a moment…

The thing I immediately noticed was this code used two different memory locations, while my program (as listed in VIC-NIC NEWS) used the same memory location twice. I consulted a VIC-20 memory map to see what all the various addresses are for:

  • 37137 – Port A output register: (PA0) Bit 0=Serial CLK IN, (PA1) Bit 1=Serial DATA IN, (PA2) Bit 2=Joy 0, (PA3) Bit 3=Joy 1, (PA4) Bit 4=Joy 2, (PA5) Bit 5 = Lightpen/Fire button, (PA6) Bit 6=Cassette switch sense, (PA7) Bit 7=Serial ATN out
  • 37151 – Port A (Sense cassette switch)
  • 37152 – Port B output register: keyboard column scan, (PB3) Bit 3 =cassette write line, (PB7) Bit 7 =Joy 3
  • 37154 – Data direction register B

The TORPET code looked wrong since one of the locations it was using had nothing to do with the joystick.

The Atari Magazine looked better since it used the two locations that mentioned joystick – 37137 and 37152. 37137 contains three joystick directions (Joy 0-2) plus the button. 37152 contains the final joystick direction (Joy 3). However, running this code doesn’t show anything changing for “right”.

I think the extra POKEs the code I used (and the code in The TORPET used) may explain that. It seems you have to POKE to change the purpose of some of this bits. 37154 is a data direction register for Port B (37152), and before my joystick code I POKE it to 127 which is a binary pattern of 01111111. After doing the joystick PEEK, the code POKEs it to 255, which is 11111111. I am suspecting that that 0 (bit 7) indicates read of whatever is hooked to that bit — which is Joy 3 (PB7). It looks like you turn it to 0, then you can PEEK it, then it gets set back to a 1 after.

I added this to the Atari Magazine code:

5 POKE 37154,127
10 PRINT PEEK(37137), PEEK(37152) : GOTO 10

…and now the second value changes when the joystick is pressed right. Huzzah!

It looks like the first byte reads up, down, left and fire, and the second is right. The POKE is only used to toggle the right bit on and off to do a read. It should get restored after (set back to 1) but in my quick demo, I didn’t bother to do that and I found I could not type certain keys. Aha, that explains “keyboard column scan.” That bit must be used to read a keyboard column, normally, and can be switched to read the joystick instead.

I will have to explore that more, later, but for now I can clearly see an issue with my code. By using only one of those locations, it is never reading the I/O bit that represents the “right” direction.

The code listed in The TORPET is incorrect:

9000 POKE 37154,127
9010 JO= (NOT((PEEK(37152)AND128) /8+( PEEK(37151)AND60)/4)) +32
9020 POKE 37154,255
9030 RETURN

37151 does not have anything to do with the joystick. This code takes the PEEK of that location and ANDs it with 60 (bit pattern 00111100) telling me it is expecting to use four bits. That matches the four joystick bits that are at 37137:

  • Bit 2 – (PA2) Bit 2=Joy 0
  • Bit 3 – (PA3) Bit 3=Joy 1
  • Bit 4 – (PA4) Bit 4=Joy 2
  • Bit 5 – (PA5) Bit 5 = Lightpen/Fire button

I think The TORPET got it wrong, and that second PEEK should be 37137.

The PEEK of 37152 seems okay. It ANDs it with 128 (bit pattern 10000000) which matches looking for that bit for the joystick:

  • Bit 7 – (PB7) Bit 7 =Joy 3

I suspect Atari Magazine just omitted the POKE needed to have the bits come from the joystick port, and The TORPET just had the wrong address listed. Since I had never heard of The TORPET, I expect I got my code from one of the few magazines I had at the time (Family Computing, Compute or Compute’s Gazette).

I changed my code to use 37137, but it still did not work! Now I could only move to the right by pressing Up+Right.

I think it is time to figure out what this code is trying to do.

Figuring out what this code is trying to do

Let’s start with the “correct” TORPET code and dissect what it is doing:

J=(NOT((PEEK(37152)AND128) /8+( PEEK(37137)AND60)/4)) +32
  • 37137 – Port A output register: (PA0) Bit 0=Serial CLK IN, (PA1) Bit 1=Serial DATA IN, (PA2) Bit 2=Joy 0, (PA3) Bit 3=Joy 1, (PA4) Bit 4=Joy 2, (PA5) Bit 5 = Lightpen/Fire button, (PA6) Bit 6=Cassette switch sense, (PA7) Bit 7=Serial ATN out
  • 37152 – Port B output register: keyboard column scan, (PB3) Bit 3 =cassette write line, (PB7) Bit 7 =Joy 3

PEEK(37152) uses “AND 128” to get just the high bit (bit 7) of Port B, which is the “right” joystick direction. It will either be 0 (no right) or 128 (right). It then divides by 8 which effectively shifts that bit over three places to the right:

10000000 - 128 (original reading)
00010000 - 16 (after the divide by 8)

PEEK(37137) uses “AND 60” to mask out the four bits in the middle. If they were all “on” (you can’t do that with a normal joystick), it would read 00111100. It then divides by 4 which effectively shifts those bits over two places:

00111100 - 60 (original reading if all joystick inputs were "on")
00001111 - 15 (after the divide by 4)

It adds those two values together, so this code is creating a new value of 5 bits, where those five bits represent the joystick switches for up, down, left, right and fire (00011111). From looking at the bit pattern, this new byte represents the following:

  • Bit 0 – Up
  • Bit 1 – Down
  • Bit 2 – Left
  • Bit 3 – Fire
  • Bit 4 – Right

Next I wondered why the program uses “NOT.” From checking the PEEKs, I see that when a joystick switch is not on, it shows a 1. When it is activated, it shows a 0. The NOT is used to invert that logic:

If no switches are pressed, the value is 31 (00011111). NOT flips the bits, so that value becomes 11100000. (Actually, I think it is represented as 16-bits, so 11111111111000000.) I believe when you use AND/OR/etc. the value is treated as a 16-bit signed value (-32768 to 32767) with the high bit representing negative. There result is the 31 becomes a -32. This explains the “+32” at the end.

The result is a value that is 0 if no switches are pressed. All of this match (dividing, adding, NOTing) does make the routine slow so maybe we’ll play with speeding it up sometime…

Using this newly created bit pattern, the BASIC program could use specific values to represent a direction (up), or two directions at the same time (up+left). My game did not use the fire button, but I think the way you would check that would be to use AND on the JO value to look for that specific bit, that way the rest of the value could be anything (up+fire, up+left+fire, nothing+fire, etc.).

Here is a test program for the “fixed” TORPET code:

10 rem fixed torpet code
20 gosub 9000
30 if jo and 1 then print "up ";
40 if jo and 2 then print "down ";
50 if jo and 4 then print "left ";
60 if jo and 8 then print "fire ";
70 if jo and 16 then print "right";
80 if jo<>0 then print
90 goto 20
9000 poke 37154,127
9010 jo=(not((peek(37152)and128)/8+(peek(37137)and60)/4))+32
9020 poke 37154,255
9030 return

Though, a mystery I Have yet to understand, is why do so many VIC-20 joystick references say you can also use 37152 and 37151? This code also works:

9010 jo=(not((peek(37152)and128)/8+(peek(37151)and60)/4))+32

Anyone know?

Now … why did I use Up and Down in my original Eggs? I think this is because the joystick code I had was broken and never returned a value for right. This was because it was PEEKing the same byte twice instead of the second byte being the one that had the “right” switch! I probably couldn’t get it to work, so I just used UP and DOWN.

Using this “fixed” code, I could now alter my program to work like I originally intended:

0 rem 2024/2/11 fixed joystick
1 print"{clear}{down*3} eggs"
2 print"{down*3} by allen huffman"
3 print"{down*2}vic-nic news july 1983"
4 forj=1to5000:next
5 poke36879,8:printchr$(147)
10 b=8130:m=3:sc=0
15 e=int(rnd(1)*20)+7703
20 printchr$(19);chr$(5);"score:";sc
25 pokeb,21:pokee,81
30 poke37154,127
35 j=(not((peek(37152)and128)/8+(peek(37137)and60)/4))+32
40 poke37154,255
45 ifj=0then80
50 pokeb,32
55 ifj=4thenb=b-1
60 ifj=16thenb=b+1
65 ifb=8120thenb=b+1
70 ifb=8141thenb=b-1
75 pokeb,21
80 pokee,32
85 e=e+22
90 pokee,81
95 ife=>8120ande=bthen110
100 ife=>8120ande<>bthen115
105 goto25
110 sc=sc+10:pokee,32:goto15
115 m=m-1:pokee,32
120 ifm=0then135
125 goto15
135 fort=1to5:printchr$(17):next
140 fort=1to6:printchr$(32);:next
145 printchr$(158);"game over"
150 print"{down*2}play again? y/n"
155 geta$:ifa$="y"thenrun
160 ifa$="n"thenend
165 goto155

And now, while I still wonder why so many VIC articles disagree on how to read the joystick, at least I can move left and right in my 1983 classic VIC-20 game Eggs…

Until next time…

Let’s write Lights Out in BASIC – part 3

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

The story so far… In the beginning, we learned a bit about the game Lights Out and its history. We then saw some very basic BASIC that implements the basic functionality of a basic game of this type. We still have a bit more work to do, such as initializing some of the squares to an “on” state and adding code to detect when the game has been won.

Let’s add that.

Game Initialization

Since variables in BASIC initialize as 0, and 0 means FALSE (the light is “off”), the initial grid would be shown with all lights off. Congratulations. You win!

To make it a game, we need to have some or all of those lights on when the game starts. My initial attempts of just randomly setting some number of lights to on seemed to often produce puzzles that could not be solved — even when using lookup tables (i.e., “cheating”) that show the winning patterns. Are there unsolvable patterns in Lights Out???

I consulted the chat section of the BING search engine, and asked it…

Yes, there are some configurations of the Lights Out game that cannot be solved. In fact, Marlow Anderson and Todd Feil proved in 1998 that not all configurations are solvable. However, it is important to note that these unsolvable configurations are not valid Lights Out puzzles.

– BING AI Chat

Well then. Since unsolvable patterns are not valid for Lights Out, tust turning on random lights is not an acceptable way to start a game.

Side Note: Card games like Solitaire certainly can be unwinnable depending on the order of cards in the deck. I am pretty sure games like Minesweeper are like that, too. But Lights Out patterns are always supposed to be winnable.

It seemed if you started with all lights off, you could simply work backwards by toggling lights on randomly until you got to a stopping point. Whatever pattern that is, the player was assured that there was a way to win. Instead of just turning on specific lights, I could just select a square and allow it to do the normal toggle (that light, plus the adjacent lights).

For my version, I will just make a very simple “initialize game” routine that does this. To do this, I will use a FOR/NEXT loop and generate random X/Y coordinates and call the “toggle” subroutine. This should end up with a random pattern that is 100% solvable.

4000 REM INITIALIZE GRID
4010 PRINT "INITIALIZING..."
4020 FOR A=1 TO 10
4030 X=RND(5)-1
4040 Y=RND(5)-1
4050 GOSUB 3000
4060 NEXT
4070 RETURN

This is what it is doing:

  • Line 4010 – Since the FOR/NEXT loop will cause a pause, I wanted to print out something to tell the player what was happening.
  • Line 4020 – A FOR/NEXT loop is done so the random grid selections can be done 10 times. (We’ll improve this later.)
  • Line 4030 – For X, RND is used to choose a number from 1 to 5. Since the DIM arrays are base-0 (0-4), we subtract 1 so Y will be a number form 0-4.
  • Line 4040 – Same thing, but for Y.
  • Line 4050 – We GOSUB to the routine that toggles the specific square (X,Y), and any adjacent squares.
  • Line 4060 – Continue the FOR/NEXT loop…
  • Line 4070 – We return back to wherever we were GOSUB’d from.

At the start of the game, we’d just “GOSUB 4000” to initialize the grid. Here is the complete code, so far:

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

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
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

4000 REM INITIALIZE GRID
4010 PRINT "INITIALIZING..."
4020 FOR A=1 TO 10
4030 Y=RND(5)-1
4040 X=RND(5)-1
4050 GOSUB 3000
4060 NEXT
4070 RETURN

And it works! Even on a 1980 4K TRS-80 Color Computer (shown here, emulated in XRoar):

But the game still cannot be won because there is no code to check for a win ;-)

Defining a “Win”

Since the goal of Lights Out is to turn all the lights out, winning means that the number of lights that are on is zero. One simple (but slow) way to test for this condition would be to scan through the entire grid and add up how many lights are on.

5000 REM COUNT LIGHTS ON
5005 LO=0
5010 FOR Y=0 TO 4
5020 FOR X=0 TO 4
5030 IF L(X,Y) THEN LO=LO+1
5040 NEXT
5050 NEXT
5060 RETURN

To check, that routine is called. If LO=0 then the game has been won. Since the routine counts the number of “on” lights,, the user could also be told how many lights are on. I would probably add this right after it draws the grid, so the final winning grid is shown before the game ends.

10 REM INITIALIZE GRID
20 GOSUB 4000
30 REM SHOW GRID
40 GOSUB 1000
45 REM CHECK FOR WIN
46 GOSUB 5000
47 IF LO=0 THEN PRINT "YOU WON!":END
48 PRINT "LIGHTS ON:";LO
50 REM INPUT SQUARE
60 GOSUB 2000
70 REM TOGGLE SQUARES
80 GOSUB 3000
90 REM REPEAT
100 GOTO 30

For a small 5×5 grid, the CoCo seems plenty fast enough to do this check without much of a delay in between moves. If the machine were very slow, or the grid was very large (and thus, took much longer to check), this might not be the best approach.

Another option might be to start with a count of all lights that are on, and decrement that value each time a light is turned off. If a light is turned on, increment it. If the value reaches zero, the game has been won.

But how do we know which lights are on? We’d could just call our “count lights that are on” function after the grid is initialized and get that value.

Or, maybe we don’t use that routine at all. We could put the count routine directly in the routine that toggles the squares on and off:

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

We could increment some variable every time a light is turned on, and decrement it any time a light is turned off.

It looks like our shortcut of using NOT is going to cause us more work. Since we aren’t manually setting the value to something meaning ON, and something else meaning OFF, we have no place add code to increment or decrement our Lights On count. Had we used 1 for on, and -1 for off, we could just add the value of the square (1 or -1) and been done.

But we didn’t.

We know after the NOT toggle, the value will be -1 or 0. Had it been 1 and -1, counting would be very straightforward. But with -1 and 0, we need to somehow make the -1 (meaning TRUE, a light was turned on) be an increment (+1), and the 0 (meaning FALSE, a light was turned off) to be a decrement (-1).

Side Note: There are many ways to write a program. In this one, I chose an easy way to toggle the lights. At the time, I was not considering counting the lights that were on. This NOT approach adds a bit more work to do the count. It could be that adding extra work here might be larger/slower than just doing a count routine that scans the whole grid. Depending on if we are going for speed or memory usage, the design decisions may need to be different.

Mapping this out, I find a simple solution. I can multiply the value (-1 or 0) by 2, and then add 1.

  • If the value is -1, multiplying by 2 will make it -2. Then adding 1 will make it -1.
  • If the value is 0, multiplying by 2 will be 0. Then adding 1 will make it 1.
ON: -1 * 2 = -2 + 1 = -1

OFF: 0 * 2 = 0 + 1 = 1

Well, that gets us a +/- 1, but it is backwards from what I would have preferred. To work around that, I can subtract the value. If you subtract -1, it is like adding one. And if you subtract 1, it is like adding a -1. Easy! :)

The updated routine looks like this:

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

Yuck. But hey, it works!

Now, instead of calling the “count all the squares” routine, we can just reset the LO “lights on” variable during the initialization routine, and it should be decremented/incremented as the game plays.

To test, let’s comment out the call that counts the squares:

10 REM INITIALIZE GRID
20 GOSUB 4000
30 REM SHOW GRID
40 GOSUB 1000
45 REM CHECK FOR WIN
46 REM GOSUB 5000
47 IF LO=0 THEN PRINT "YOU WON!":END
48 PRINT "LIGHTS ON:";LO
50 REM INPUT SQUARE
60 GOSUB 2000
70 REM TOGGLE SQUARES
80 GOSUB 3000
90 REM REPEAT
100 GOTO 30

I did a quick test, and this appears to work. It is also faster, since it bypasses the small delay that was happening each time it called the “count all 25 squares” routine. Nice.

Again, the overhead of adding the count in five locations (about 21 bytes each, so 100 bytes extra) does appear to be larger than the “count all the squares” routine. If code size were more important than speed, the count routine would make more sense.

But so far, it still fits on my 1980 4K CoCo with 1514 bytes left to spare (and more room once I remove the un-used “count all the squares” routine). We can add more code! :)

We now have a very primitive but functional version of Lights Out that should guarantee each “random” pattern can be won. The “random” patterns should keep someone from just learning the moves and repeating them to win the level if they play it over and over.

Except they may not be as random as we think.

To be continued…

VIC-NIC News located! My first published program!

Updates:

  • 2024-02-10 – Added screen shots, and pasted in the code.

On February 2, 2024, I received an e-mail with the subject: Eggs program

Could this be someone who had a copy of the VIC-NIC News newsletter where my “Eggs” VIC-20 program appeared? The e-mail read:

Hi Allen,

I saw on your website you were looking for a copy of your Eggs program listing that was in The Vic-Nic News magazine.

I went through the issues I have (#1 thru 7) and found the listing in #6. If you still need it, I can scan the page and email it to you or copy it and mail it.

Take care,

(name to be added, pending permission)

– e-mail received on 2/2/2024

I replied back:

“Proof that VIC-NIC NEWS actually existed! I would very much like a scan of that issue. Actually, since this is so difficult to find, would you be willing to scan them all so we could get them uploaded somewhere? Maybe archive.org?

But yes. Please yes. I would very much like that. Very much.”

– my e-mail reply

And today, I received a scan of my Eggs program! I had pretty much given up ever finding a copy.

Thank you thank you thank you!

I recognize my doodles, but had forgotten I sent drawings in. Actually, I believe I sent the program in typed up via a typewriter. The instructions and the “ASCII art” representation of the game screen were typed by me, and the doodles were added. Actually, I did have some kind of thermal printer for my VIC-20, so perhaps I included the program printed out that way (I see it has a few embedded screen control codes in a few PRINT statements). It is very exciting to see this again.

Very, very cool.

I typed it in to CBM prg Studio so I could play it:

1 print"{clear}{down*3}      eggs"
2 print"{down*3} by allen huffman"
3 print"{down*2}vic-nic news july 1983"
4 forj=1to5000:next
5 poke36879,8:printchr$(147)
10 b=8130:m=3:sc=0
15 e=int(rnd(1)*20)+7703
20 printchr$(19);chr$(5);"score:";sc
25 pokeb,21:pokee,81
30 poke37154,127
35 j=(not((peek(37151)and128)/8+(peek(37151)and60)/4))+32
40 poke37154,255
45 ifj=16then80
50 pokeb,32
55 ifj=18thenb=b-1
60 ifj=17thenb=b+1
65 ifb=8120thenb=b+1
70 ifb=8141thenb=b-1
75 pokeb,21
80 pokee,32
85 e=e+22
90 pokee,81
95 ife=>8120ande=bthen110
100 ife=>8120ande<>bthen115
105 goto25
110 sc=sc+10:pokee,32:goto15
115 m=m-1:pokee,32
120 ifm=0then135
125 goto15
135 fort=1to5:printchr$(17):next
140 fort=1to6:printchr$(32);:next
145 printchr$(158);"game over"
150 print"{down*2}play again? y/n"
155 geta$:ifa$="y"thenrun
160 ifa$="n"thenend
165 goto155

There may still be some typos, and I think there may be an issue with the PEEKs used to read the joystick. Currently, the Mac version of the VICE Emulator has a bug an joysticks don’t work (well, the fire button does, but nothing else). I will test it on my TheVIC20 machine soon.

And here it is in all its glory!

Title Screen – I think they made this title screen. I hope I would have centered things better, if I had done it.

Game Play – A “U” for the players “bucket” (B variable), and a ball for the falling “egg” (E variable):

Game Over – And the inevitable game over screen.

To be continued…

The most mysterious song(s) on the internet

In recent years, YouTube decided I had an interest in “lost media.” Famous examples of lost media include the episodes of Doctor Who that were not saved by the BBC. Over the years, many episodes have been recovered as copies were found in personal collections or at overseas TV stations. Perhaps my interest in Doctor Who is what led YouTube to decide I was interested in lost media.

In recent years, a video called “the most mysterious song on the internet” caught my attention. I do not remember which video I first watched, but today there are hundreds of copycat videos that regurgitate the same information over and over. Basically, there is a recording of part of a song with lyrics folks think are singing “Like the Wind.” Music identification services like Shazam cannot match the song, so for years folks have been trying to figure out where the song came from.

Wikipedia entry: The Most Mysterious Song on the Internet – Wikipedia

Another example is a song being called “Everyone Knows That” which is an 80s pop sounding song that most thought was a female singer, but today many are thinking it was actually a male. This song, also, has yet to be identified.

Wikipedia entry: Everyone Knows That (Ulterior Motives) – Wikipedia

I wanted to share an example of something that would 100% be considered “lost media” if someone shared a clip today: Y99.

I don’t actually know if that was the name of the song, but I seem to recall it actually singing that — and that would have been a clue to help locate the song. Back in the 1980s, a local radio station in East Texas held “battle of the band” contests. This was before I moved there (Y99 the radio station no longer existed, becoming 99.3 KUEZ which was easy listening then, later, oldies). A winner of the contest got some recording studio time, and a number of vinyl single records were produced of their song.

A guitar player I knew had one of these singles, and he played it for us. This song was also played on the radio as part of the contest prize. Beyond anyone hearing it on that one small East Texas radio station, or owning one of a handful of single copies, the song basically does not exist. If the band did not make it big and bring that song with them, the story of “Y99” would have ended there. (Though, I think folks would have figured out Y99 was a radio station.)

And this was in deep East Texas. Similar contests with recording studio prizes likely happened more often in larger markets, especially back in the day when “battle of the bands” was a more common concept.

Like The Wind” could has been such a song, and someone recorded it when it played on their local radio station. Just being on radio doesn’t mean it was some big artist backed by a major record label. (Indeed, I have had dozens of things I have made played on local radio stations–usually parody or comedy songs–and those existed nowhere else except there, and on my hard drive.)

Everyone Knows That” is suspected of being recorded from TV, which makes a “battle of the bands” concept a bit less likely but still possible. Over the years, one-time performances of various songs have appeared on TV for talent shows, fundraisers, etc. so I really have no thoughts on that one.

And of course, anyone who has ever worked in radio probably remembers all the “music libraries” stations would license for use in commercials. Some are just music, and others have vocals–usually with an option to sing at the start and end with music in the middle to talk over (a “donut”), or some combination of that.

Few ever owned any of these records/tapes/discs beyond radio stations. I could pull a track from my “Instant Access Music” collection that I bet no one could find.

Just some thoughts.

I hope one day they find these (and other) similar songs.

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…