Monthly Archives: February 2024

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.