Category Archives: Retro Computing

The CHANGE command on PDP8 BASIC is weird. And neat.

Recently, Rick “Shanghai” Adams pointed me to a BASIC program he was working on for a PDP-8. Much like I now spend my time playing with BASIC from 1980 on a CoCo 1 emulator, Rick is going even further back and playing with a version of BASIC from a machine created in the 1960s.

And its a bit different.

I have previously posted about this machine (well, PDP systems in general) when I was trying to find the origins of the INSTR command in BASIC. Then I was able to dig up a 1971 PDP-11 manual that referenced this function for that BASIC.

Rick sent me a link to a two-player game called CHOMP. I was unfamiliar with it, but see it has its own wiki page.

https://en.wikipedia.org/wiki/Chomp

On that entry, it is presented as a chocolate bar made up of squares you can break off. The top left square is poison, so whoever takes that final piece loses.

By Lord Belbury – Own work, CC BY-SA 4.0, https://commons.wikimedia.org/w/index.php?curid=86379139

This helps me understand why the came is called CHOMP.

But I digress… This really has nothing to do with that game, though CHOMP will likely return in a future blog post here.

BASIC may have been cooler in the 1960s…

Rick has a BASIC preprocessor that allows him to write easy to read source code, then convert it into messy BASIC code with line numbers later. Here is a Guest The Number game from Rick’s GitHub:

https://github.com/yggdrasilradio/b8pp/blob/master/guess.txt

	' Generate random number
randomize
x = int(100 * rnd(0)) + 1

' Intro
print "I'VE THOUGHT OF A NUMBER BETWEEN 1 AND 100."
print "CAN YOU GUESS WHAT IT IS?"

n = 0
60 n = n + 1
print
print "YOUR GUESS";
input g
if g <> x then 130

' Player wins!
print
print "YOU GUESSED IT IN"; n; "GUESSES!"

if n <= 7 then 120
print "BUT IT SHOULD HAVE ONLY TAKEN YOU 7 GUESSES."

120 stop

130 if g > x then 160
print "TOO LOW."
goto 60

160 print "TOO HIGH."
goto 60

end

That text is processed by his script and becomes this:

https://github.com/yggdrasilradio/b8pp/blob/master/guess.bas

1RANDOM\X=INT(100*RND(0))+1
2PRINT"I'VE THOUGHT OF A NUMBER BETWEEN 1 AND 100."
3PRINT"CAN YOU GUESS WHAT IT IS?"\N=0
60N=N+1\PRINT\PRINT"YOUR GUESS";\INPUTG\IFG<>XTHEN130\PRINT
61PRINT"YOU GUESSED IT IN";N;"GUESSES!"\IFN<=7THEN120
62PRINT"BUT IT SHOULD HAVE ONLY TAKEN YOU 7 GUESSES."
120STOP
130IFG>XTHEN160\PRINT"TOO LOW."\GOTO60
160PRINT"TOO HIGH."\GOTO60\END

…and that is the code that he loads and runs on the PDP emulator.

The first thing you will notice is the use of a backslash. Initially, I thought this was just in place of a colon. For example, I see things like:

PRINT "TOO HIGH"\GOTO 60

…and that looks like it is just…

PRINT "TOO HIGH":GOTO 60

…but once I started converting PDP CHOMP to work on the CoCo, I realized that was not the intent of the backslash there. It appears to be a way to have multiple lines without line numbers. The logic does not continue to flow through those slashes:

60N=N+1\PRINT\PRINT"YOUR GUESS";\INPUTG\IFG<>XTHEN130\PRINT

Above, if G is not equal to X, it goes to line 130. There is a PRINT after that which would NEVER be reached if these were just colons:

60N=N+1:PRINT:PRINT"YOUR GUESS";:INPUTG:IFG<>XTHEN130:PRINT

To port this to Microsoft Color BASIC, I would have to do something like this:

60 N=N+1:PRINT:PRINT"YOUR GUESS";:INPUTG:IFG<>XTHEN130
61 PRINT

And guess what? That is also not important to this blog post. But might be later to a follow up blog post about porting PDP BASIC CHOMP to CoCo BASIC CHOMP.

CHANGE is … good?

Rick has entered the Logiker Christmas Challenge in the past with entries done in this much earlier BASIC. I have seen him comment on the far more limited STRING handling in that version of BASIC which required some very different approaches to the challenges.

Now I understand what he means.

While looking at his CHOMP source code, there is a keyword I had never seen before – CHANGE. He explained it to me:

“The CHANGE statement converts strings to and from an array, and the zeroth element of the array is the length of the string”

– Rick Adams

I saw it used like this:

40	print
print "YOUR MOVE";
input m$
change m$ to m

Or, in the converted BASIC:

40PRINT\PRINT"YOUR MOVE";\INPUTM$\CHANGEM$TOM

So if you did something like this:

M$="ABC"
CHANGE M$ TO M

…then you would get this:

FOR I=0 TO M(0):PRINT M(I):NEXT
3
65
66
67
  • M(0) is the length of the converted string.
  • M(1) is the first character of the string (“A”)
  • M(2) is the second character of the string (“B)”
  • M(3) is the third character of the string (“C”)

That’s kinda neat. To do the same thing on Color BASIC, we could make subroutines like this:

2000 'M TO M$
2010 M$="":FORZ=1TOM(0):M$=M$+CHR$(M(Z)):NEXT:RETURN

3000 'M$ TO M
3010 M(0)=LEN(M$):FORZ=1TOM(0):M(Z)=ASC(MID$(M$,Z)):NEXT:RETURN

And then we could change “CHANGE M$ TO M” to “GOSUB 3000” and “CHANGE M TO M$” to GOSUB 2000.

10 INPUT M$:GOSUB 3000
20 FOR I=0 TO M(0):PRINT M(I):NEXT:END

Or reverse it, if we created one manually:

10 M(0)=3:M(1)=65:M(2)=66:M(3)=67:GOSUB 2000
20 PRINT M$:END

Though Rick pointed out with MID$() and such available, there would be far easier ways to do this. But those subroutines are what I will be using so I can more directly run his PDP BASIC code with minimal changes.

Have you ever worked on a BASIC that used the CHANGE command? If so, what was it? Leave a comment, please.

Until next time…

Revisiting PUT defined by ASCII strings

This is a followup (and correction) to my PUT defined by ASCII strings article. That article, itself, was a followup to my Extended Color BASIC PUT from DATA article. They both discuss a method to use the GET/PUT graphics commands with pre-loaded data to PUT on the screen, rather than having to render/draw something first and then GET it so you could PUT it later.

I post such articles for two main reasons:

  1. So I can learn from all the much-smarter programmers who leave comments with advice/suggestions/corrections.
  2. So I can find it again when I’ve forgotten how it worked.

#2 is what led me to my article as I wanted to use the code for another experiment. And that’s when I realized my original PUTDATA.BAS program had a bug: it PUTs the tanks flipped vertically!

The program defined 8×8 characters as ASCII strings. I used a tank with four versions – one for each direction. They looked like this:

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"

A routine READs those strings from the DATA statements, then walks through the characters looking for an “X”. If it finds one, it sets a bit in a number variable. At the end of the scan, it now has a byte value which can be loaded into the PUT data.

However, my routine to scan the strings does it backwards and the image is reversed left-to-right:

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

I did not notice this until I tried to use this code for a new experiment, and it was not PUTting what I expected. But for the tanks, being symmetrical, I did not catch it in my original demo. The UP and DOWN tanks looked correct, and I failed to notice my LEFT and RIGHT tanks were reversed.

The bug is from the loop at line 460 that walks through the bits from 1 to 8, and uses that value as the index into the string using MID$. A bit from 1 to 8 is rightmost to leftmost, but on a string, 1 to 8 is leftmost to rightmost. One of them needs to work backwards.

Since I already do some math to calculate the bit (to base-0 counting, 0-7 instead of 1-8), I just made my change there:

470 'FASTER WAY
480 IF MID$(Z$,BT,1)="X" THEN V=V+BT(8-BT)
490 'SLOW WAY
500 'IF MID$(Z$,BT,1)="X" THEN V=V+2^(8-BT)

Now I get the tanks facing the proper directions my test program PUTs them on the screen: UP, DOWN, LEFT then RIGHT.

I have added this code to my GitHub repository in “CoCo Programs” under “basic”:

https://github.com/allenhuffman/CoCo-Programs/tree/main/basic/tank

And here is the full version with the fix:

0 'PUTDATA2.BAS (FIXED BUG)
1 '2026-05-06
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(8-BT)
490 'SLOW WAY
500 'IF MID$(Z$,BT,1)="X" THEN V=V+2^(8-BT)
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 "

Until next bug … I mean, time. Until next time…

Backrooms movie used a BBS to promote the film. Sorta.

The recently released Backrooms movie is set in the old timey year of 1990. Some fun things were used to promote the movie. For example, this TV commercial was released (apparently shown on the Pluto TV streaming service):

In the ads a 408 area code telephone number. Calling that number got you to a fax machine, so folks figured out they could connect using FAX protocol and it would fax back a flyer.

There was also a Bulletin Board System (BBS) set up! Sorta. Since the days of dialup BBSes are long gone, a web site acting as a BBS Archive went live This allowed you to register for an account with the BBS and, once approved, log in via the website. You could then explore this BBS as it existed in 1990:

https://www.408bbsarchive.net

There were messages to read, and even the real Terms of Service which took AGES to scroll through at the simulated 2400 baud rate.

…and I actually scrolled through every page and captured screen shots.

There were also some files that could be downloaded:

ENTER.TXT

https://enter.backrooms.mov

ACCESS.TXT

=================================================
*** EXCLUSIVE OFFER -- LIMITED TIME ***
=================================================

Purchase your BACKROOMS ticket early at:
https://backrooms.mov

Advance buyers receive EXCLUSIVE ACCESS to
a local 408 business hat, available only
through this offer.

=================================================

SIZE.TXT

https://shop.a24films.com/products/backrooms-wallpaper

But how good of a BBS is it? I have thoughts. And, I actually starting using BBSes before I even had my own computer back around 1982. A classmate taught me about them, and we’d go down to a local Radio Shack and they’d let us use their TRS-80 Model 3s to dial in to Houston BBSes. Great times!

Nitpicking the Backrooms BBS

So … how good of a BBS would this have been in 1990? Let’s see…

No 40 column option

It is unsurprising that a BBS from 1990 would be using 80 columns. While there were still plenty of non-PC users (Commodore, Radio Shack, Apple, etc.) calling into BBSes back then, there were plenty of systems that natively displayed 80 columns (Atari ST, Commodore Amiga, and even later 8-bit systems like the Commodore 128 and Tandy Color Computer 3 all had 80 column displays). There were certainly plenty of 80 column only systems by that point, but most flexible BBS software still would let you set your screen width.

Use of PC-Only character set

What makes this look like a PC was the use of the “enter” symbol (a down then left arrow) found on IBM-PC keyboards of the day. I do not recall ever seeing that on any BBS screens I had visited. Was this common on PC-BOARD or some other MS-DOS BBS system? It was created using a left arrow and a “down and to the left” text character block, so it could have existed on a real PC BBS of the day.

https://en.wikipedia.org/wiki/Code_page_437

BUT, only the PCs with that character set could have seen this. It would have been some other type of characters for non-PCs. Only some PC emulating terminal program could have displayed it on a Commodore or such. On the CoCo 3, the only one that likely would have worked would be Twilight Terminal by SockMaster, which simulated ANSI colors and IMB PC character sets, and maybe NetMate by Roger Taylor. I am unsure if either of these would have been available in 1990.

But I digress. My point is, I would have expected a BBS in the heart of Silicon Valley to have supported more than just PCs in 1990.

Use of e-mail address for an account

Obviously, a BBS back in 1990 would not have used an e-mail address for an account. Most would let you enter your real name (or an alias), and a password, and perhaps a phone number. Some BBS SysOps (system operators) would call you up to make sure you were real before verifying your account.

But wait, it’s Unix!

The website shows a command prompt:

The “cu” utility is a Unix command (“call unix”) for serial connections. This implies the website is some kind of Unix machine and is dialing a number that is still in service. It is a neat simulation, but not something most of the BBS users in 1990 would have ever used unless they were at a university or some corporation with Unix systems that had modems.

And yes, I did try to alter the command line and change the baud rate. It did not allow it.

Content is key…

And, of course, the main thing is that there was only a handful of messages ;-) Whatever this system was in 1990, it was barely being used by anyone ;-)

Just repeat to yourself: it’s just a show!

But hey, it was a cool promotion, even if it wasn’t likely a BBS any of us would have wanted to use (or even been able to, if we were non-PC users).

For further reading…

Here is a website listing the various things that were done to promote the film:

https://kane-pixels-backrooms.fandom.com/wiki/Backrooms_(film)/ARG_Marketing

Had the Commodore 64 not been $600…

…that would have been my next computer after my Commodore VIC-20. $600 back in 1983 would be over $2000 in 2026. There was really no way I was talking my grandmother in to buying me a $2000 home computer back when folks were still unsure why anyone would want a home computer.

But, if I did, I’d be much more excited about the return of Commodore. The FPGA recreation, where they are making them using the original molds from the 1980s, has sold over 20,000 units. Likewise, reports of TheC64 (an emulator that looks like a mini C64) estimated to have sold over 300,000 units tells me the love Commodore users had for their 8-bit machines still lives on the same way it does in our CoCo community for our 8-bit systems.

Commodore 64 for sale at Best Buy?

Today I learned that the replica Commodore 64s are for sale at Best Buy (for shipment only, through a third party seller):

https://www.bestbuy.com/site/searchpage.jsp?id=pcat17071&st=Commodore

We live in wonderful times.

Historically, the C64 is the “largest selling computer model of all time” — a feat we will likely never see beaten since modern PCs and Macs have such a short lifespan on store shelves before they are replaced by a different model. While overall there have been more Macs or PCs sold, those have all been different models over the years. (This is the main thing I had against “more PCs sold than Macs” back in the 1990s — you were comparing thousands and thousands of different PC models collectively against a handful of Mac models; but as soon as you compared individual models, the iMac was one of the largest models sold of any computer of its era.)

And the VIC-20, too!

The VIC-20 was far from the best selling system of its era, yet even it got a TheVIC20 release in a full size replica model with an emulator inside. I had to order main from the UK, so it annoyingly has the “correct” spelling of Colour instead of the Americanized version ;-)

Replica Commodore VIC-20: TheVIC20.

There have also been replicas of things like the ZX Spectrum and other “obscure to us in the USA” models.

Maybe one day they will come for our community and we’ll see a mainstream emulator replica of a CoCo.

One can hope.

Congrats, new Commodore. Maybe I can finally get that C64 I would have loved to have 40 years ago.

CoCo smooth scrolling.

Can someone please “explain this to me like I’m five”:

https://www.6809.org.uk/xroar/online/?-run=512scroll.cas

Click that link to see it run in the web browser. This screen shot does not really show how it looks running:

It shows a CoCo 32×16 text screen smoothy scrolling semigraphics blocks and text characters up the screen. The note that the SAM is not involved is also something I need a child-like explanation of. What does the SAM actually do that would be part of such a technique?

GFXFLIP2.BAS – scrolling a PMODE 4 screen.

In a post to the CoCo mailing list, Juan Castro said this:

“… I was trying to comment on this post – https://subethasoftware.com/2026/05/19/where-does-cocos-pmode-graphics-memory-start/#comment-42465 – and I was trying to say this:

In GFXFLIP.BAS, instead of the ‘flip through them’ code, try this:

1000 ‘GO DO THE ROTATION
1010 GOTO 1050
1020 FOR P=2 TO 5:GOSUB 1070:PMODE 4,P:SCREEN1:NEXT
1030 IF INKEY$=”” THEN 1030
1040 FOR P=4 TO 1 STEP -1:GOSUB 1070:PMODE 4,P:SCREEN1:NEXT
1050 IF INKEY$=”” THEN 1050
1060 GOTO 1020
1070 FOR TT=0 TO 40:NEXT:RETURN

– Juan Casto via CoCo Mailing list

So let’s take a look and see what it does. Replacing my code from 70-110 with a GOSUB to this routine gives us this:

0 'GFXFLIP2.BAS
1 'Juan Castro
10 PCLEAR 8
15 ' DRAW FIRST SCREEN
20 PMODE 4,1:PCLS:SCREEN 1,1
30 CIRCLE(128,96),50
35 ' DRAW SECOND SCREEN
40 PMODE 4,5:PCLS:SCREEN 1,1
50 LINE (10,10)-(245,171),PSET,B
60 ' FLIP THROUGH THEM
70 GOSUB 1000
110 GOTO 70

1000 'GO DO THE ROTATION
1010 GOTO 1050
1020 FOR P=2 TO 5:GOSUB 1070:PMODE 4,P:SCREEN1:NEXT
1030 IF INKEY$="" THEN 1030
1040 FOR P=4 TO 1 STEP -1:GOSUB 1070:PMODE 4,P:SCREEN1:NEXT
1050 IF INKEY$="" THEN 1050
1060 GOTO 1020
1070 FOR TT=0 TO 40:NEXT:RETURN

…and when you run it, you will see it takes the PMODE 4 screen (which is 4 blocks of graphics memory) then goes in a loop where it starts the displayed screen at block 2, then 3, then 4, then 5. With a small delay in-between each change, it shows (initially) the first PMODE 4 screen (blocks 1-4), then it toggles the memory displayed through each block until the start is block 5. This makes the screen appear to scroll up in chunks (1/4th of the screen each time). The process is then reversed to scroll back down.

Neat trick.

Stupid VARPTR tricks

A recent e-mail exchange with CoCo user Torsten D. inspired me to try something stupid.

The Radio Shack Color Computer gained the VARPTR command in the Extended BASIC ROM. As has been discussed here many times, VARPTR returns the memory location of a 5-byte variable descriptor. There are actually seven bytes total, since the two bytes before the VARPTR address is the two byte variable name.

0 'MAKE42-1.BAS
10 DIM A,B,C:A=42:B=VARPTR(A)
20 FOR C=B-2 TO B+4
30 PRINT C,PEEK(C):NEXT

Running this will show the full seven bytes required to represent the A variable:

VARPTR is returning 9792 as the location of the start of the 5-byte floating point value for the numeric A variable. The two bytes before it are the variable name: 65 (uppercase “A”) and 0 (no second letter). Had the variable name been “AA” that would be 65 65.

The five bytes of 134, 40, 0, 0 and 0 are the floating point representation of 42.0.

If you got the VARPTR address of one numeric variable, and of a second numeric variable, you could just copy those five bytes and clone the variable value:

0 'MAKE42-2.BAS
10 DIM A,B,I
20 A=42:B=0
30 PRINT "A =";A,"B =";B
40 FOR I=0 TO 4:POKE VARPTR(B)+I,PEEK(VARPTR(A)+I):NEXT
50 PRINT "A =";A,"B =";B

If you run this, you will see output showing “A = 42” and “B = 0”, followed by output showing “A = 42” and “B = 42”. The code in line 40 copies the five bytes (offset 0 to 4) from the VARPTR address of variable A into the VARPTR address of variable B.

But why would you want to do that?

B=A is would have been much simpler.

Here’s where it gets more stupid…

And if you can clone a variable, you could also change a variable if you knew what five bytes represented the number you wanted. In the first example, we saw that the five bytes that represent 42.0 are 134, 40, 0, 0 and 0. Knowing that, you could do something like this:

0 'MAKE42-3.BAS
10 DIM A,V
20 PRINT "A =";A
30 V=VARPTR(A):POKE V,134:POKE V+1,40: POKE V+2,0:POKE V+3,0:POKE V+4,0
40 PRINT "A =";A

The “DIM” is not really needed in this example, but it is a good habit to get into if you want to control the order your variables exist in the variable table. Variables that need to be the fastest should be at the front of the list, and variables use infrequently or ones that can be slow can be at the end.

But I digress.

The point of this stupid code is that an “A” variable is created with 0 as its default value, then VARPTR is used to see where that variable is in memory. Five POKE commands put that floating point representation of 42.0 into that variable’s storage… So when you print A, you get a value of 42, even though A=42 (or indeed, A= ANYTHING) was nowhere in the program.

I have no idea why you would want to do that.

Until next time…

Clock Signal emulator

I just learned about the Clock Signal emulator:

https://github.com/TomHarte/CLK

The author recently joined the Cocopedia.com and has updated some technical sections with information he has learned in adding support for the CoCo. Clock Signal is described as:

“A latency-hating emulator of: the Acorn Electron, BBC Micro and Archimedes, Amstrad CPC, Apple II/II+/IIe and early Macintosh, Atari 2600 and ST, ColecoVision, Enterprise 64/128, Commodore Vic-20 and Amiga, MSX 1/2, Oric 1/Atmos, early PC compatibles, Sega Master System, Sinclair ZX80/81 and ZX Spectrum, and Thomson MO5/6.”

https://github.com/TomHarte/CLK

The author is adding CoCo to this list. As someone who started out with a Commodore VIC-20, then went to the CoCo, I am intrigued to find another emulator that will do both. (MAME/MESS also does both.) There is currently early support for the CoCo in there, but it only boots a CoCo Color BASIC 1.2 ROM:

I was able to download Clock Signal from GitHub, then open the Xcode project on my Mac, change one setting, then build and run. Neat!

When you first run one of the emulators, it will prompt you to drag in the needed ROMs:

Drag them into that window, then it’s ready to go. Pretty easy.

I know little beyond this, but plan to play with this a bit and try to get some of the other systems up and running.

One downside is that it looks like there may not be a Windows version.

To be continued…

Where does CoCo’s PMODE graphics memory start?

When I got my first Radio Shack TRS-80 Color Computer 1 back around 1983, I dove into the Getting Started manuals and learned all the new wonderful commands that EXTENDED COLOR BASIC offered me that my Commodore VIC-20 did not have. Commands like PLAY for music, SOUND for a beep, and graphics commands to draw CIRCLEs, LINEs and even DRAW complex objects were … amazing.

On my original tape based CoCo (EXTENDED COLOR BASIC) the high-resolution graphics memory started just after the memory used for the 32×16 text screen:

DEC     HEX     DESCRIPTION
----- ---- -----------
0 0000 Color BASIC Use
512 0400 Text Screen
1536 0600 Hi-Rez Graphics

Knowing that, as I learned some 6809 assembly language I wrote routines to scroll a PMODE 4 256×192 graphics screen. I used this to do video titles for my dad. I’d create a screen using a graphics program, and load that into the second half of the graphics memory, then let my routine smooth scroll that screen into view.

I’d love to find that old source code and see how awfully inefficient it was. I bet one of you could really show me a faster way to do it.

But I digress…

DISK EXTENDED BASIC changed everything!

The next major leap in home computing for me was getting a disk drive for my CoCo. Imagine being able to store up to 156K of data on a floppy disk, and load things at such blazing speed (compared to the tape player and it’s 1500 baud rate).

It was nice… but it broke my assembly code! It turned out, when DISK BASIC was added, it used memory after the text screen for its own purposes, and shifted the high resolution graphics memory 2K further down in the memory map:

DEC     HEX     DESCRIPTION
----- ---- -----------
0 0000 Color BASIC Use
512 0400 Text Screen
1536 0600 Disk BASIC Use
3584 0E00 Hi-Rez Graphics

Learning this, I adjusted my assembly routines to work on graphics screens starting at 3584 (disk systems) rather than 1536 (tape systems).

How do we know?

I wondered if there was some programmatic way to tell where the screen started. I don’t think this even dawned on me back in the 1980s, but I asked this question to the new Color Computer mailing list and quickly got an answer:

Word at $BC (GRPRAM) is start of graphics RAM. Word at $BA (BEGGRP) gets you the start of the current view window.

Juan Castro
Enviado do meu Olivetti Programma 101
http://retropolis.com.br

Bonus. Not only can you tell where graphics memory starts, but you can tell which page is displayed. With EXTENDED BASIC, you have 8 1.5K pages of graphics memory you can use. You reserve them with the PCLEAR command (it defaults to 4 pages). You can learn more about PCLEAR in this article.

PMODE 3 (128×192 4-color) and PMODE 4 (256×192 2-color) both need 4 pages, so you can have two screens in those modes. PMODE 0 uses 1 page, so you can have 8 pages in that ode.

  • PMODE 0 – 128×96 2-color (1536 bytes)
  • PMODE 1 – 128×96 4-color (3072 bytes)
  • PMODE 2 – 128×192 2-color (3072 bytes)
  • PMODE 3 – 128×192 4-color (6144 bytes)
  • PMODE 4 – 256×192 2-color (6144 bytes)

When you use PMODE, the first parameter is the graphics mode, and the second is which page for the screen to start on. For PMODE 4 you can do “PMODE 4,1” to get one screen of 4 pages starting at page 1, and “PMODE 4,5” to get a second screen of 4 pages starting at page 5. You can set PMODE to the first screen and draw something, then set it to the second screen and draw something different, then flip back and forth between them using PMODE. Here is a silly example:

0 'GFXFLIP.BAS
10 PCLEAR 8
15 ' DRAW FIRST SCREEN
20 PMODE 4,1:PCLS:SCREEN 1,1
30 CIRCLE(128,96),50
35 ' DRAW SECOND SCREEN
40 PMODE 4,5:PCLS:SCREEN 1,1
50 LINE (10,10)-(245,171),PSET,B
60 ' FLIP THROUGH THEM
70 PMODE 4,1:SCREEN 1,1
80 FOR A=1 TO 100:NEXT
90 PMODE 4,5:SCREEN 1,1
100 FOR A=1 TO 100:NEXT
110 GOTO 70

That program will reserve all 8 pages, then set a PMODE 4 screen starting at page 1. It draws a circle on that page. Then it sets a PMODE 4 screen starting at page 5. It draws a box on that screen. After that it just toggles between showing PMODE 4 starting at page 1, then at page 5, and the image will flicker back and forth between the circle screen and the square screen.

With low-resolution PMODE 0, you can do 8 screens of animation this way.

I wrote a second program that will print out where screen memory starts, and where the current viewed page starts.

0 ' SCRSTART.BAS
1 ' THANK YOU, JUAN CARLOS!
10 PCLEAR 8
20 FOR P=1 TO 8:PMODE 0,P
30 PRINT PEEK(&HBC)*256+PEEK(&HBD),PEEK(&HBA)*256+PEEK(&HBB)
40 NEXT P

When I run this on an tape-based EXTENDED BASIC CoCo (emulator) with no Disk Controller, it shows graphics memory starts at 1536 and then it toggles through each PMODE 0 page to show where each one would start:

And when DISK EXTENDED BASIC is used, the same program shows the memory locations starting 2K higher in memory:

Thank you, Juan Carlos, for telling me this. I wish I had known about this back then. I could have made my assembly program automatically find the start of the graphics screen rather than having to assembly separate versions for tape or disk systems.

Until next time…