Category Archives: Retro Computing

Unraveling the mysteries of Color TRSDOS

UPDATES:

  • 2026-07-21 – Typo (thanks, Tim L.).

NOTE: The author of this work will be referred to as Abraham Lincoln ;-) per this comment: “Thanks! But I’m terribly modest and shy away from attention. So, I humbly request that you refer to me as “Abraham Lincoln”.” ;-)

TRSDOS was the name of the disk operating system that Radio Shack used on their TRS-80 computers.

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

There were alternative DOSes available, but TRSDOS is where it started, and what shipped with the original machines. As I write this post, I see that the last version of TRSDOS was released 42 years ago.

When the TRS-80 Color Computer came out in 1980, it was a T.I.N.O. – “TRS-80 In Name Only”. The 80 in TRS-80 came from the Zilog Z-80 processor, and the Color Computer used a Motorola 6809 processor. I assume Tandy just wanted to leverage the popularity of the TRS-80 brand and continue using that name. The use of TRS-80 continued even into 1983 when Tandy brought out its first PC-compatible-ish machine, the Tandy 2000. Officially called the “Tandy” 2000, the badge on the front of the machine still read “Tandy TRS-80.” This was, according to the always-accurate Wikipedia, the final use of TRS-80 branding on a Radio Shack computer. When the more-PC-compatible-ish Tandy 1000 came out in 1984, it was solely a Tandy-branded machine.

But I digress.

TRSDOS was never a thing for the CoCo. There was no disk operating system. Instead, the CoCo booted into a ROM BASIC. When a Disk Controller was added, it contained another ROM that extended the basic with new disk-related commands. DISK EXTENDED BASIC was not an operating system, but most of us referred to it as “RS-DOS” (Radio Shack DOS, one would presume). I am unsure when we started calling it RS-DOS. This would be a good side quest to research. I assume by the time OS-9 (an actual disk operating system) was released, we would have needed some way to tell if a program ran from DISK BASIC or required OS-9.

But I digress, again.

Color TRSDOS was a thing.

Color TRSDOS did exist, but perhaps it was another T.I.N.O. – this time meaning “TRSDOS In Name Only”. Color TRSDOS was included with the DISK EDTASM 6809 assembler. In the manual was a source code listing and on the disk was a DOS.BIN binary and DOS.BAS loader program that was Color TRSDOS.

DISK EDTASM – directory

But what was Color TRSDOS?

What was Color TRSDOS?

If you do a RUN”DOS” form the Disk EDTASM disk, you are greeted with a menu:

Color TRSDOS – menu

The name “R.G. Kilgus” is instantly recognizable to early adopters of the CoCo. R.G. created some of the earliest Radio Shack programs for to CoCo, including the infamous Dino Wars!

https://www.lcurtisboyle.com/nitros9/dinowars.html

As you may be able to tell from the screenshot, Color TRSDOS was not a DOS like we might expect. Normally, a DOS boots up into a command line that lets you run programs. MS-DOS is probably the most iconic DOS that comes to mind for me:

Instead, Color TRSDOS seemed to be more of a library of disk routines that one could use with their own 6809 assembly programs. BASIC documented a few “official” ROM calls that could be called from assembly routines to do things like print a character to the screen or input a character from the keyboard. DISK BASIC added one that could read or write raw data to a disk. This was very low level, and there was no ROM call to do things like read a directory, create a new file, delete an existing file, or anything else. This means assembly language programmers had to figure that out and write all that code themselves.

Color TRSDOS appears to have been Radio Shack’s official solution for this. You could use the Color TRSDOS assembly language routines in your own programs and get higher level disk functionality, such as the things shown in the Color TRSDOS menu.

Side Note: What was the license agreement for Color TRSDOS? Could that code be included in commercial sold software, or was it only allowed to be used for personal programs? Anyone know?

Maybe I ran into Color TRSDOS in some CoCo program I used over the years. There were certainly many programs that could load/save files to disk and show directories. Maybe some of these made use of the Color TRSDOS routines. Does anyone know of any program that ever used the Color TRSDOS routines?

What could Color TRSDOS do?

It appears Color TRSDOS has a way to load and execute a binary program, as demonstrated from menu option #2:

Color TRSDOS – Exec a Program

There was also support for a software clock, as demonstrated by menu option #3. It would put an incrementing Hour/Minute/Second value in the top corner of the screen:

Color TRSDOS – Start Clock Display

The Color Computer used the video circuitry to generate a 60Hz signal (also used by the TIMER command in BASIC). It was common for software clocks to make use of this and track time, though this time would drift any time interrupts were masked — such as when accessing a disk.

I have not explored the code myself, but I assume Color TRSDOS just provided a simple software clock for programs to use.

Option #4 would display the Disk Allocation Map. This display showed which granules on the disk were in use. From looking at the display, you can see it represents the 68 granules (9 256-byte sectors, 2304 bytes) that make up an RS-DOS disk. It looks like “.” indicates the granule is free, “X” may indicate all of the 9 of the 256-byte sectors in that granule are used, and a number may indicate how many sectors are used (if less than 9).

Color TRSDOS – Disk Allocation Map (DAM)

I have discussed DISK EXTENDED BASIC’s format and this Disk Allocation Map in previous blog posts. Check that link to learn more about granules and such.

Option #5 showed a simple interface to copy a file, either between the same disk or to separate disks. To copy a file to the same disk in Disk BASIC, you’d do something like this:

COPY "FILE.BAS" TO "NEWFILE.BAS"

This basically duplicated the file, and required a different name for the copy.

To copy a file from Drive 0 to Drive 1:

COPY "FILE.BAS:0" TO "FILE.BAS:1"

But BASIC had no way to copy between separate disks if you only had one disk drive. It looks like this Color TRSDOS program may have a way to do that, where it would read data from the disk, then tell you to swap in the second disk, then write it out there. (I did not test this.)

Color TRSDOS – Copy Files

Last, option #6 performed a disk directory. I am unsure how this works, since it initially shows nothing and has some fields where you can type. Perhaps this supported some level of wild cards?

UPDATE: After I wrote this, I went back to try it. You can arrow over to the extension field and enter “BAS” then it only showed the “DOS.BAS” file. Neat! Perhaps wildcard support is built in to the Color TRSDOS routines?

Color TRSDOS – Directory

And, of course, error handling…

Color TRSDOS – Error

It looks kinda neat. Had I realized this back then, I could have been adding disk support to my own assembly programs. I really didn’t know it was a thing.

Color TRSDOS is a thing, again!

Well, maybe I get a second chance now. Thanks to the tireless efforts of Abraham Lincoln, Color TRSDOS has been archived to GitHub. In a Facebook CoCo group post dated June 20 2026, he wrote:

“. . . I found an OCR scan of the Disk EDTASM manual and was able to copy-paste the source code from that. There were LOTS and LOTS and LOTS of errors introduced via the OCR scanning process, but I was able to resolve everything, and even correct a bug that was in the original manual (as determined from the non-OCR version) but subsequently fixed in the DOS.BIN executable that shipped with Disk EDTASM.

Now we can generate the exact DOS.BIN executable from source. I went through this exercise so that anyone who is interested can study, learn from, and incorporate the code into their projects, if they’d like. For me, in particular, I wanted to be able to explore it to understand the interface that Tandy expected assembly language developers to use for accessing the disk files so that I could create a command shell that provides the same interface to the programs that it launches.”

– “Abraham Lincoln” on Facebook

Thank you for your service, Abraham! You can find the result of Abraham’s work, as well as progress on a new command line interface, on his GitHub page:

https://github.com/DarkChocoholicDev/ColorTRSDOS

Abraham has also shown the beginning of a command line TRSDOS interface. I look forward to seeing how this turns out. Maybe we will end up with a “real” TRSDOS for the CoCo thanks to his efforts.

To be continued?

SockMasters 2-way scrolling in BASIC

Hat tip to L. Curtis Boyle for pointing this one out to me. Published in The World of ’68 Micros back in 1995 was an article by John “SockMaster’ Kowalski demonstrating how to do smooth horizontal scrolling on the CoCo 3 in the 320×200 16-color graphics mode.

In BASIC.

With no assembly.

You can find this demo in Volume 2, Number 5 in an article called “The Seven-line demo: an amazing achievement with DECB!” I must have been fully into OS-9 by this point since this article does not seem familiar to me. I was not really keeping up with any BASIC stuff by that point, having moved to OS-9 assembly and C programming.

Here is that program as I typed it in and adjusted some spacing, with a few comments added by me. The only crucial part is line 70 which must have 11 colons and five spaces after that POKE Q,G line.

0 'The World of '68 Micros
1 'Volume 2, Issue 5
2 REM ** 2WAYSCRL.BAS
4 REM **bySockMaster
10 POKE 65497,0:HSCREEN 2:FOR G=0 TO 15:READ A:PALETTE G,A:NEXT
20 DATA 0,19,22,50,54,52,38,37,44,45,41,13,11,25,27,26
30 FOR G=0 TO 319 STEP .5:HSET(G,RND(191),RND(15)):NEXT
40 C=1:S=40:FOR G=15 TO 1 STEP-1:HCOLOR G
50 HCIRCLE(310-G*5,48),S:HPAINT(310-G*5,48):S=S-2.6:HLINE(RND(110)+210,RND(80)+104)-(RND(110)+210,RND(80)+104),PSET,BF:NEXT
60 Q=65439:W=0:E=127
65 '11 COLONS, 5 SPACES
70 FOR G=0 TO 127:PALETTE W,W:POKE Q,G::::::::::: POKE Q,E-G:NEXT:GOTO 70

I am unsure if the other spaces in line 70 are critical. The original listing looked like it had a lot of spaces between keywords and such, but that should not matter. LINE 70, being a loop, would be made a bit slower with extra spaces. Here is how it was presented in the magazine:

Here is what it does when ran in the XRoar emulator:

Spiffy!

Now I am off to read the full article to better understand how this works.

Jim Gerrie’s REVERSE PRINT routine

I created a new category for MC-10 and Micro Color BASIC for this one…

If you do not recognize the name Jim Gerrie, start here:

http://jimgerrie.blogspot.com

You will find dozens … hundreds … thousands (?) of programs there for the Radio Shack TRS-80 MC-10 computer, as well as the Color Computer. I believe he is by far the most prolific programmer in our community.

Recently, he shared a video on his YouTube channel of a 1979 Star Trek game he ported to the MC-10:

I am always fascinated at his porting efforts. He has done some amazing arcade conversions scaled down to fit the 32×16 text screen (ahem, 64×32 “graphical” blocks).

What caught my attention on this one was how he prints out the header row and column:

The Motorola MC6847 VDG chip used by the MC-10 and the Color Computer had a limited font of uppercase letters and numbers, with no lowercase versions. Instead of lowercase, the VDG contained the same set of characters but in reverse mode. I’ve posted about this in the past:

Now, I knew that the Micro Color BASIC of the MC-10 had some extra features we never got on Color BASIC for the CoCo. The MC-10 keyboard had the 2×2 graphic block characters by the keys, and you could type them with the keyboard. Here is what the MC-10 keyboard looks like, via an image from the online MC-10 emulator:

https://mc-10.com

I believe SHIFT+LETTER would produce that graphical block. To change the colors, CONTROL-0 would toggle through them. This allowed you to embed these colorful block characters in a PRINT statement or string. Nice!

Heck, the CoCo didn’t even HAVE a Control key until the CoCo 3 came out in 1986, and our “Super” Extended Color BASIC did nothing with the extra keys they added.

But I digress.

I thought maybe there was some way to type reverse video directly from the keyboard. On the CoCo and MC-10, SHIFT-0 toggles between UPPERCASE and lowercase (which is represented by reverse video). BUT, spaces, numbers, and special characters still print normally. It is a “lowercase” mode, after all, and there is no such thing as a lowercase 7.

I left a comment to the video, asking how this is done. Jim responded with this:

0 DIMC1,C2,M$:M=16384:GOTO10
7 C1=(PEEK(17024)AND1)*256+PEEK(17025)+16383:FORC2=1TOLEN(M$):POKEC1+C2,ASC(MID$(M$,C2))AND63:NEXT:?@C1-M+C2,;:RETURN
10 PRINT:INPUT M$:GOSUB7:GOTO10

The Coco peeks are: 136 (17024) and 137 (17025). And of course swap 1024 for 16384.

– Jim Gerrie via YouTube https://www.youtube.com/watch?v=o08AfAIfThM

It appears to be a custom display routine that will take what is in M$ and POKE the values to the screen in inverted format. I expected the 136 and 137 locations had something to do with screen cursor position. I headed over to Color BASIC Unravelled to take a look…

136 is 0x88 in hex (eh, &H88 to Extended BASIC), so I searched for that in the book’s memory map and confirmed:

CURPOS for the win!

Dissecting the code…

0 DIMC1,C2,M$:M=16384:GOTO10
7 C1=(PEEK(17024)AND1)*256+PEEK(17025)+16383:FORC2=1TOLEN(M$):POKEC1+C2,ASC(MID$(M$,C2))AND63:NEXT:?@C1-M+C2,;:RETURN
10 PRINT:INPUT M$:GOSUB7:GOTO10

…goes like this:

  • LINE 0 – Pre-allocated variables C1, C2 and M$. BASIC will dynamically allocate variables when they are first used, but you can use DIM to allocate them ahead of time, and in the order you specify. Variables at the start of the variable table are found quicker than variables at the end because BASIC has to scan through table to find the variable each time it is used. M points to the start of the text screen on the MC-10 (that would be 1024 for the CoCo). GOTO10 would be replaced by whatever line number is the program startup/initialization. Jim is very aware of how the BASIC interpreters work, so he puts his subroutines at the top of the pgoram. Anywhere you are in the program, whether that is line 100 or line 63000, GOSUB 7 will be able to find that routine by only having to skip through any lines from 0-6 to get there. Sadly, we learned to put subroutines at the end of our programs, so every GOSUB had to scan forward through every line until it found the subroutine line.
  • LINE 10 – Skipping ahead, this is the “program” for this example. PRINT to skip a line, then INPUT to input a string, then a GOSUB 7 to display that string, and GOTO 10 to repeat.
  • LINE 7 – Now the fun begins. C1 is … uh … okay, let’s take a quick break.

In Jim’s YouTube comment, he mentioned that 136/137 are the CoCo values, and 17024/17025 were the MC-10 values. These correspond to the 16-bit value stored there, which represents where in memory the cursor currently is. On a CoCo, if you use CLS to clear the screen and home the cursor, that position will be 1024. Let’s see if that matches:

CLS:PRINT PEEK(136)*256+PEEK(137)
1024
OK

Checks out. On the MC-10, that would be “CLS:PRINT PEEK(17024)*256+PEEK(17025)” and that will display 16384 – the start of the MC-10s text screen in memory.

So far so good. Jim’s code starts out by getting those two values and adding 16383 to them for some reason. He also does an “AND 1” to the first peek, which should mask off all the bits in that 8-bit value except for the first one, meaning it should be either a 1 or a 0. But why?

On the MC-10, when the cursor is at the top left of the screen, 17024 and 17025 should represent 16384. That would be 64*256+0. As the cursor moves forward, that second value goes from 0 to 255, halfway in to the screen memory. Then, that second number flips back to zero and the first number goes up by one.

The first half of the screen is 64*256+(0 to 255) then the second half is 65*256+(0 to 255). This program will poke an orange block to the first byte of the screen, and the last byte:

10 REM MC-10
20 CLS
30 POKE 64*256+0,255
40 POKE 65*256+255,255

But Jim is doing something with that “AND 1”. 64 AND 1 is 1, since bit 0 is set. 65 AND 1 is zero, since bit 0 is clear for an odd number. Thus, his code is using 0 for the first half of the screen, and 1 for the second half, so he adds 16383 to the value which puts it back into the screen memory range of 16384 to 16895.

But why? If Jim is doing this, there has to be a reason. I wrote this test to find out.

0 REM MC-10 REVERSE1.BAS
10 FOR P=0 TO 510
20 CLS:PRINT@P,".";:PRINT@P,;
30 L=PEEK(17024)*256+PEEK(17025)
40 PRINT@500,L;
50 IF INKEY$="" THEN 50
60 NEXT

This will clear the screen, print a dot at a position, then move the cursor position back to where the dot is. This lets me “see” where the location is. It then PEEKs to get the current cursor position, and prints it on the bottom row. Hit a key, then it repeats. You can see the dot walk across the screen as the value at the bottom increases.

Okay.

Modifying the program to use the AND 1 would look like this:

0 REM MC-10 REVERSE2.BAS
10 FOR P=0 TO 510
20 CLS:PRINT@P,".";:PRINT@P,;
30 L=(PEEK(17024)AND1)*256+PEEK(17025)+16383
40 PRINT@500,L;
50 IF INKEY$="" THEN 50
60 NEXT

And running that looks … the same.

And that’s when I realized what this code does! The AND 1 makes it return values 0-511 for the curious position — the PRINT@ locations. He must use this code with AND 1 (without the +16383) when he is using PRINT@. If he wanted the POKE location, he would leave out the AND 1 and the +16383, and just have the POKE positions.

I feel dumb that I did not realize it. But this was fun anyway. This may be the first MC-10 program I have ever written.

Moving back to the code…

  • LINE 10
    • C1 is set to the memory location of the current cursor position.
    • C2 is then used as a loop from 1 to the length of the M$ to display.
    • POKE C1 (current cursor position) plus C2 makes the POKE location move forward with the loop.
    • For what to POKE, he uses ASC to get the ASCII value of the corresponding character in the string. He is using a trick here. We all learned MID$(A$,5,1) to get the 1 character at position 5. But if you leave off that third parameter, it will return a new string that starts at position 5 and goes to the end of the string, the same as a RIGHT$ would do. But ASC doesn’t care. If you ASC(“HELLO”) it gives you ASCII of the first character, “H”. A nice shortcut.
    • After this, that ASCII value is AND 63 which masks off higher bits, to the value will be 0-63. And if you POKE those values to the screen, you get reversed video. That is the trick to how this works.
    • After that is a PRINT@ to move the cursor to where the new position should be (POKEing bytes to the screen bypasses BASIC so the cursor would still be where it was). Even though C1 is a screen POKE location, M was the start of the screen, so he can subtract that to turn it back into a PRINT@ location.

That’s cool. So let’s try it on the CoCo:

0 DIMC1,C2,M$:M=1024:GOTO10
7 C1=(PEEK(136)AND1)*256+PEEK(137)+1023:FORC2=1TOLEN(M$):POKEC1+C2,ASC(MID$(M$,C2))AND63:NEXT:?@C1-M+C2,;:RETURN
10 PRINT:INPUT M$:GOSUB7:GOTO10

Tada!

I wish I had thought of that back in the 1980s. I could have made my CoCo programs look spiffier.

Thanks for sharing, Jim!

Until next time…

VIC-20 BASIC is better than CoCo BASIC for…

…at least this one thing.

In the old 8-bit Microsoft BASICs, the tokenizer routine scans the input line and converts keywords into one or two byte tokens. This crunches the line down so it takes up less memory, and speeds up execution since the detokenizer just has to grab a token then run the related function. If BASIC were stored as ASCII text, it would have to scan the line text and parse multiple bytes to figure out it is a “PRINT” versus just looking at a one byte token.

In Color BASIC on the Radio Shack Color Computer, the tokenizer needs a space between variable names and keywords so it can tell where the variable stops and the keyword begins. For example:

IFSC=100THEN500

That line works fine, since “SC” (a score variable in this case) is followed by an equal sign. BASIC can find it easily. But if you were comparing against another variable:

IFSC>HSTHEN500

…you would get an ?SN ERROR on that line. I believe this is because Color BASIC “supports” longer variable names, but only honors the first two characters. Thus, these are all the same variable:

LO=1
LONG=1
LONGER=1
LONGEST=1

They are recognized as LO In the “IFSC>HSTHEN500” example, how is BASIC to know that we are using “HS” versus “HST” or even “HSTHEN” as a variable? It must be scanning until it hits something that is clearly not part of a variable name.

To make things even more confusing — variable names begin with a letter and can end with a number (or numbers, that are ignored), you can make variable names like this:

HSTHEN500=10
OK

PRINT HSTHEN500
10

And with that understanding, of course a space is required after variables before the following token. You have to add one between the variable and the next keyword:

IFSC>HS THEN500

BASIC can easily figure out where SC starts since a variable cannot contain a “>”, but it needs the space to know where HS ends. Thus, a FOR/NEXT loop like this requires spaces.

I fired up the “work in progress” Tandy CoCo engine in the cool Clock Signal emulator to test it out.

And then VIC-20 enters the arena…

But my VIC-20 did not need the space. Its parser can figure this out. Once again, I used the Clock Signal emulator which also has VIC-20.

When I was relearning VIC-20 a few years ago, I ran into this difference and wondered why. As I began revisiting it recently, I thought maybe the VIC-20 does not allow longer variable names, and has a better way to tell where a variable ends? I tried to use “START=1” but got an error. “Ah, it must not!” But then I found “ST=1” also did not work, and assumed “ST” must be some kind of reserved keyword.

Oddly, “AAAAA=1” works, and shows the same value as “AABBB=5”. For that test, it works like Color BASIC.

But “LO=1” works while “LON=1” does not work. Is LON some keyword too??? I clearly never learned all the keywords when I had my VIC.

SUPERMAN=1
SUPERGIRL=2

PRINT SU
2

I guess the VIC-20 BASIC does work like Color BASIC, but with some different keywords making the VIC-20 list of forbidden variables different than the CoCo’s list of forbidden variables. (See that link — I’ve now written about this at least three times, before this post.)

When I had my VIC-20, I did not know Microsoft had created the BASIC it uses. It just says “CBM BASIC” so I’d always thought (back then) that Commodore Business Machines wrote their own BASIC. It wasn’t until the modern Internet that I learned Microsoft wrote the 6502 BASIC used by Commodore. (If you have never dug into this, check it out sometime. There is some interesting history between Microsoft and Commodore. Apparently, that’s what led Microsoft into placing hidden “MICROSOFT” easter eggs in their other BASICs to be able to prove it was their code. But I digress…)

I find this interesting. I do not know 6502 assembly, but I am tempted to try to find the VIC-20 equivalent of “Color BASIC Unravelled” and see if I can learn how the Microsoft 6502 BASIC parser works compared to their 6809 parser.

But hopefully one of you knows, and can tell us all in the comments.

Until then…

What you PSET is not always what you PPOINT

Let’s consider this a part 2 for this 2024 post:

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

Read that first, then come back. I’ll wait.

Ready… PSET… GO!

In Microsoft Extended Color BASIC on the Radio Shack Color Computer, high resolution graphics command were added. There were fancy commands like DRAW for drawing complex designs, then simpler command like LINE and CIRCLE.

Even simpler was the PSET command which would set an individual pixel on the screen. This was the high resolution equivalent of SET in Color BASIC for the text screen (64×32 blocks).

I had a Commodore VIC-20 at the time, but remember getting a call from my Radio Shack sales guy, Don, to tell me they had just gotten in a new Extended BASIC that I should come out. I did, and fell instantly in love with being able to do things with simple commands versus confusing POKEs on my VIC.

I read through the manual in the store, and created programs on their CoCo. One of them used PSET to randomly place dots on the screen:

0 'RNDPSET.BAS
10 PMODE 3,1:PCLS:SCREEN 1,1
20 PSET(RND(256)-1,RND(192)-1,RND(4)-1)
30 GOTO 20

Oh the fun we had back then.

Use the SCREEN 1,0 color set and you get different colors:

The PMODE 4 screen (256×192) was only two colors, white and black, but TV set (composite video, NTSC) created artifact colors that made it look weird. The emulators try to simulate this effect:

Depending on the mode the CoCo power up, even column pixels would be red and odd would be blue, or the reverse. While the CoCo 3’s video hardware could control this, on the CoCo 1 and 2 it was “random.” You could keep hitting the rest button until the colors flipped. Thus, many CoCo 1/2 games started up to a solid red (or blue) screen, expecting you to know what to do to get it the color the game wanted, or, if the programmer was fancy, it might even tell you what to do:

Paper Route by Diecom

And if the programmer was really fancy they could just handle it in software based on what you told it you saw (“Press 1 if the screen is RED, 2 if it is blue” kind of thing.)

NOTE: I wanted to include a screenshot of this but I cannot remember which games worked like that. If you know, leave a comment and I’ll update this post.

Get to the PPOINT!

PSET would put a pixel on the screen using a specific color:

The syntax is:

PSET (X, Y, C)

The C was the color, and it accepted a value of 0-8. But, you did not get nine colors on any of the high resolution screens. You got either 2 (black/green or black/buff or using the alternate color set), or 4 (green/yellow/blue/red or buff/cyan/magenta/orange using the alternate color set). You had to know the range of the 4 color values to use for the mode you were using.

Or did you?

No. The C value could be 0-8 on any graphics screen, so most programs I saw used 0-1 for two color, or 0-3 for four color. And that’s not at all how Radio Shack described it in the manual… but it worked and kept us from having to memory color ranges based on modes. (See my 2024 article, link at the top of this one, for a table showing how this worked.)

And my point is … PPOINT returns the value that “should” be used — not the value you PSET there! If you were using a screen that wanted colors 5-6-7-8 and you used colors 1-2-3-4, you could PSET color 1, but when you would PPOINT that pixel, you got back a 5 — the same color, but the value you were supposed to be using.

Thus, anyone who made use of PPOINT learned this. I did not use it, and I never learned it until 2024 in the comments to that earlier post.

So for fun, I wrote this program that cycles through each PMODE (0 to 4) and then PSETs each color value (0-8) to a pixel and then reads the pixel color back using PPOINT. It prints it out so we can see this:

The first value of the column is the C value that was used in PSET. The number after it is the return value from PPOINT. So “1) 5” means PSET(0,0,5) and P=PPOINT(0,0).

PMODE 0, PMODE 2 and PMODE 4 are a two color modes, so the range of colors you can use (0-8) are just the same two colors over and over – 0 and 5. PMODE 1 and PMODE 3 are four color modes, so you see the range repeating the same four color values over and over, different depending on the mode.

And, if you used the alternate color set (SCREEN 1,1), you got a different set of color values:

Here is the code:

10 'PPOINT0.BAS
20 'SET PIXEL USING COLOR
30 'THEN PPOINT THE COLOR
40 CLS
50 PRINT@6,"PMODES - SCREEN 1,0:"
60 PRINT STRING$(32,"-");
70 FOR M=0 TO 4
80 PMODE M,1:PCLS:SCREEN 1,0
90 PRINT:PRINT@64+M*7+1,M;
100 FOR C=0 TO 8
110 GOSUB 160
120 NEXT:NEXT

130 GOTO 130

140 'SET PIXEL WITH PSET
150 'GET PIXEL COLOR
160 PSET(0,0,C):P=PPOINT(0,0)
170 PRINT@96+M*7+32*C,USING "#) #";C;P;
180 RETURN

And slight changes for the other color set:

10 'PPOINT1.BAS
20 'SET PIXEL USING COLOR
30 'THEN PPOINT THE COLOR
40 CLS
50 PRINT@6,"PMODES - SCREEN 1,1:"
60 PRINT STRING$(32,"-");
70 FOR M=0 TO 4
80 PMODE M,1:PCLS:SCREEN 1,1
90 PRINT:PRINT@64+M*7+1,M;
100 FOR C=0 TO 8
110 GOSUB 160
120 NEXT:NEXT

130 GOTO 130

140 'SET PIXEL WITH PSET
150 'GET PIXEL COLOR
160 PSET(0,0,C):P=PPOINT(0,0)
170 PRINT@96+M*7+32*C,USING "#) #";C;P;
180 RETURN

It dawns on me now that a BASIC program could detect what screen was being used by PSETting something and then reading it back with PPOINT. Based on the number that returned, you could tell which PMODE and SCREEN was being used.

But that’s a program for a different time.

Until then…

Commodore is making a flip phone. In 2026.

If you have followed the rebirth of Commodore, you may be aware they brought out a new Commodore 64 computer. This model was using an FPGA to simulate/recreate the hardware in the original 1980s home computer, with a claim of being 99.9% compatible with existing Commodore 64 stuff.

What came next was a surprise (and even shock) to most Commodore followers: a flip phone.

https://commodore.net/callback

For $549.

The new Commodore has already taken some heat from fans and had to change an announced policy. They initially planned to lock down their new Commodore 64 to only work with the official firmware. That decision was not popular, and they changed their plans.

It seems there has been enough puzzled comments on the new flip phone that the CEO just sent out an e-mail. Here is an excerpt:

“A few years ago, my priorities changed. I became a father. And somewhere between the night feeds and the realization that I was spending entire evenings chasing likes on a glowing rectangle, I had to reckon with the kind of person I actually wanted to be. The conversations that followed, with my partner, with myself, changed my life.

I switched to a flip phone. Not as an experiment. As a decision. It became my daily driver. And I won’t pretend the first few weeks were easy. I’d catch myself reaching for it out of habit, standing in a checkout line with nothing to scroll. So I snapped it shut, put it away, and looked up. Turns out there was quite a lot going on.

But that flip phone was too dumb. And the others available were too smart. What I wanted just didn’t quite exist. I didn’t want social media, or a browser. It let the wrong things in. But I need apps like Uber, Maps, WhatsApp, HQ Music Player, and a 4K Camera. Turns out a lot of people were wrestling with the same thing. Parents. Students. People who missed being present. People who wanted the convenience of modern apps without the endless feeds. So together with a team of engineers and partners, we started building what we couldn’t find: a phone that sits comfortably between dumb and smart.

That’s why we built the Callback.”

– e-mail from Commodore, 6/22/2026

I see device addiction all around me. It is common for someone to reach for their phone and start dealing with messages as if they were life or death and can’t possibly wait until after supper. Folks are on their phones in movie theaters, in their cars at red lights, and while in bed as soon as their alarm goes off, or before going to sleep.

Such a device might be the only way these folks could break their addictions. It took me not having cell phone service for 8 years to break mine, and I still think I use my phone too much these days ;-)

But … I just wanted to add this:

Any smart phone is a dumb phone if you don’t install TikTok, Facebook, Instagram, Angry Birds, etc.

Read that again for impact.

Any smart phone can be a dumb phone. Just do not install the apps. Or if you have them installed, delete them. But folks won’t do that.

Do we expect folks who can’t delete their favorite apps to buy a whole new phone?

We shall see.

I’d kinda like to have one, but I’d just remove all the apps from an iPhone before I’d carry a flip phone in 2026.

Unless this new Commodore flip phone has a better camera.

What says you? Comment away!

A slightly faster MID$ using VARPTR

TL:DNR – This is stupid. Don’t bother trying it :)


Here is another stupid thing I had to try in Color BASIC. See also my Stupid VARPTR tricks post.

Suppose you want to horizontally scroll a string across the CoCo’s 32-column text screen. You can build a long string (up to 255 characters) and then use a FOR/NEXT loop and MID$ to print 32 characters from within that longer string.

20 CLS:CLEAR 510:DIM A$
30 A$="":FORA=32TO255:A$=A$+CHR$(A):NEXT:A$=A$+STRING$(31,128)
40 TIMER=0
50 FORA=1TO224:PRINT@256,MID$(A$,A,32);:NEXT
60 PRINTTIMER

On a CoCo 3, you get a timer result of around 330-335. On a CoCo 1/2, it is slightly faster showing around 295. (There are less BASIC keyword tokens to look for so Color BASIC is faster than Exended BASIC which is faster than Super BASIC.)

When I first started benchmarking BASIC here years ago, I was using an emulator that only ran CoCo 1/2, and it never occurred to me it would be different on the CoCo 3. #TheMoreYouKnow

As I have discussed in earlier string theory articles (quite a few relating to this topic), MID$, LEFT$ and RIGHT$ all need to create a new string containing data from the original. Suppose you have this:

A$="THIS IS A TEST"

If you trim the string to the first four characters, like this:

A$=LEFT$(A$,4)

…BASIC is basically doing this:

  1. Allocate new string space for a 4 character string.
  2. Copy the first four characters from A$ into the new string.
  3. Make A$ point to the new string, which leaves the original A$ string memory available for cleanup.

This is why you need extra string memory to use these functions. If you clear JUST enough memory to hold a ten character string, you can’t do any MID$, LEFT$ or RIGHT$ with that string.

In order to make that work, you need at least 4 extra bytes reserved for string memory so LEFT$ can make the new string before deallocating the original. And if you add 4 bytes but try to use 5, you get that ?OS ERROR (out of string space) still.

So if you have a 255 character string and you use MID$(A$,0,32) to get 32 characters from that string into a new string (or use it directly with PRINT, which will directly access that string memory without a variable needed), it has to allocate 32 bytes from the reserved string memory and copy those 32 bytes over, then you can use it (PRINT or assign to a variable or whatever).

As my sample program runs, it is allocating 32 byte strings and copying 32 bytes over each time through the loop.

VARPTR, can you help?

After recently learning a weird trick involving changing where a string variable points to for its string data, that made me wonder if you could just manipulate the string address using VARPTR and then PRINT it, and be faster than the overhead of MID$.

I just had to try this…

Here is my test program. It first builds A$ to contain character 32 (space) to character 255 (end of semigraphics characters) and then pads that with 31 black blocks to be the full 255 character string size.

Starting at line 40 is a loop that will PRINT a substring of 32 characters in a loop, starting at the first character and going to the end, making the line scroll to the left.

When done, it prints how many TIMER ticks it took to do this.

Next, starting in line 70, it makes a new B$ that is a clone of A$. (No, it doesn’t need to clone it. I could have just manipulated A$ and saved a few lines.)

It then gets the address of that string descriptor using VARPTR, and saves the size (at the first byte) and the address of the string data (third and fourth byte). This allows restoring the string after the test, since manipulating strings this way could cause problems with strings and garbage collection.

For this specific example I know that the MSB and LSB of the new string are 126 and 1 on my emulated CoCo. That means I could make the string’s starting address be one higher in that memory by incrementing the second value. Had that second value been 250, once I incremented it 5 times to 255, I’d have to increment the first one and reset the second one to 0. (Clear as mud?)

Let’s just say I got lucky enough for this test, but even if this approach DID work, it would not work on all strings based on where they are in memory. It would need extra code for that, which would slow it down even further.

I POKE to change the size of B$ to 32. Then I can go in a loop POKEing the second byte of the start address up by one each time, and simply PRINTing the string. It will print 32 bytes from wherever it thinks the string data begins. It has no idea those values are being manipulated.

When done, I print the time it took and restore the original B$ values back.

10 'VARMID.BAS
20 CLS:CLEAR 510:DIM A$
30 A$="":FORA=32TO255:A$=A$+CHR$(A):NEXT:A$=A$+STRING$(31,128)
40 TIMER=0
50 FORA=1TO224:PRINT@256,MID$(A$,A,32);:NEXT
60 PRINTTIMER
70 DIM B$,V,O2,O3,S1,S2,SS
80 ' CLONE A$. GET VARPTR OF B$.
90 ' V POINTS TO SIZE
100 ' O2-O3 POINTS TO START
110 B$=A$:V=VARPTR(B$):O2=V+2:O3=V+3
120 ' SS - SAVE SIZE
130 ' S1-S2 - SAVE START
140 SS=PEEK(V):S1=PEEK(O2):S2=PEEK(O3)
150 ' CHANGE SIZE TO 32
160 POKE V,32
170 ' CHANGE START ADDR THEN
180 ' PRINT.
190 TIMER=0
200 FORA=0TO223:POKEO3,S2+A:PRINT@256,B$;:NEXT
210 PRINTTIMER
220 ' RESTORE ORIGINAL STRING
230 POKE V,SS:POKE O2,S1:POKE O3,S2

Sadly, it is only a tiny bit faster, and if I had to take care of both address bytes in the VARPTR memory, it would be slower and, without testing this, I assume slower than just using MID$.

It was a fun experiment, but “sometimes the juice is not worth the squeeze.”

Until next time…

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