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…

Insta360 X6 in 2026?

Yesterday my news alerts showed me a posting where someone shared screenshots of registrations for the Insta360 X6. There have been rumors of the X6 since (and maybe even before) the moment the X5 model was released.

Beyond adding higher resolution and/or better low light performance, what else would justify someone upgrading from the X5? Rumors are saying this model could have a 1″ lens — something Insta360 already had years ago with the Insta360 ONE RS. That model had 6K resolution (3K per lens) which was resolution worse than the later X4 and X5 “8K” models but the larger sense allowed it to capture better images even if at a lower resolution.

Just keep in mind — there is “what the camera can do” versus “what the camera operator can do.” Someone can take a mediocre camera, play with manual settings, and post-process the image to create something that looks much better than anything you can get from a “better” camera just by pressing the button in automatic mode.

I have mostly been a point-and-shoot user since I got my first digital camera in 1996, so “what the camera can do” is usually more important to me than what some advanced photographer can do with it.

An important reminder:

Be careful trusting an honest review if they don’t disclose they have a hardware sponsor providing them with hundreds or thousands of dollars worth of product to “review”. That, in itself, is dishonest, so how can you trust the rest?

Now we wait for hundreds of vloggers and bloggers to churn endlessly over the same rumors, adding nothing useful except regurgitation.

More to come…

I cannot recommend FASTMAIL.com

In 1995, I signed up with an e-mail forwarding service called pobox.com. They would give you e-mail aliases that would then forward to whatever real e-mail account you were using at the time. The basic plan came with three aliases, and at one point I was using six. Super convienient!

They also added the ability to use those aliases to redirect to a webpage. Back then, your web address might be something long like www.geocities.com/SiliconValley/1842 (my original home page at GeoPages) or be something with a “~” in it like http://www.mcs.net/~werner/yester.html (the original location of www.yesterland.com before it had a domain). Pobox allows aliasing those so users only had to know www.pobox.com/~disneyparks and it would redirect to whatever service I was using to host my theme park photos at the time. Super convenient!

Over the years, my e-mail has moved from service to service to service, yet I never had to change any e-mail addresses with any services, or notify any of my contacts about a new address. They just used the same e-mail address I had since 1995. Super convenient!

But in 2015, Fastmail acquired Pobox.com:

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

The way they handle spam filtering is much worse (no e-mail summary, no one-click way to look at items in a web page and release/white list them, etc.). E-mails from my Softaculus (WordPress) service ALWAYS get spam filtered and they have been unable to fix this. E-mails I send to folks bounce back at the Fastmail level due to reasons I haven’t figured out. It’s a mess.

So, while I told everyone about how great POBOX.COM was for 30 years… I cannot recommend FASTMAIL.COM

But they own the e-mail I have had since 1995 so I guess I am sticking with them. At least for now…

My Sandisk Extreme USB-C drive keeps ejecting itself…

I have a 2TB Sandisk Exterme USB-C drive:

https://www.bestbuy.com/product/sandisk-extreme-portable-2tb-external-usb-c-nvme-ssd-black/JXJ62C9ZSV

Though, when I bought it, it was significantly cheaper than today’s price.

For “some time now” (many months) I have been seeing this popup on my computer:

Sandisk ejection notice.

Until recently, I had assumed Apple changed something and when I “eject” and the icon disappears from the desktop it really was not ejected yet. Perhaps some background cleanup was being done that didn’t use to happen. I would then eject using Disk Utility instead, and wait for the item to become grey, indicating fully un-mounted.

However, now that I am watching for this, I will see multiple alerts like this piled up in my Notification Center in the morning. This one, for example, was after I cleared all my notifications yesterday. I have not touched the drive or intentionally ejected it. Meanwhile, the four other drives plugged up are behaving fine.

And this drive is plugged directly into my computer versus the others going into a Caldigit TS3 thunderbolt dock. I would have expected more issues from going though a dock than connecting directly.

I am posting this to get it into the search engines. Anyone else ran into this?

Hard drive prices, amirite?

Three years ago I bought a 4TB Samsung external SSD from Best Buy for $328. I thought that was expensive, but I needed it.

But that same drive today, at the same place, is over $1000.

And I still think that is expensive ;-)

But at least they have it in stock for local pickup, and you get a $100 gift card with purchase.

And yes, I noticed that the monthly payment ends in .42 cents.

Bonus Content

Here is what Amazon shows for price history:

I guess I can wait a bit longer before buying a new hard drive…

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…

Silly Atari VCS Adventure Challenges

Note for the pedantic: Atari’s Adventure was released in March 1980 for the Atari VCS. That machine was renamed in November 1982 to the Atari 2600. Thus, this game was released for the Atari VCS. Thank you for coming to my TED Talk.


I remember replaying Adventure at a friend’s house when I lived in Mesquite, Texas back in 1980. Although I don’t think I really figured the game out until some year(s) later, at some point I did. Even decades later, I can still fire up the game on my ATGames system and play it all the way through. At some point, I learned how to navigate the mazes and, for whatever reason, that still remains in my memory cells.

When you “master” something (no, I do not claim to be a master; I can merely win the game, eventually) you sometimes try to find other ways to amuse yourself. I am therefore compiling a list of all the Silly Atari VCS Adventure Challenges I can find.

All Objects in One Room Challenge

This is where I started. Carrying every object you find into the same room is easy enough, but you also have to deal with getting the dragons and that stupid bat there. Here is a video I made of doing this some years ago:

Locking Dragons in a Castle

This one comes from a comment left on an Official Atari Facebook post:

“I prefer to lock all the dragons and bat in the white castle and depending on my mood, sometimes with the white key inside to make it impossible for them all to get out and for you to re-enter.”

– Paul B., comment o Atari Facebook page

Well, now I have to try that. I should ask if the dragons have to be alive or dead ;-)

And more?

What other challenges do you have? There are certainly Speed Runs. Should that go here as well?

Leave a comment and let’s begin building the list.

Or, even better, just tell me someone has already done this, and I’ll just point to them. Less work for me :)

Thank you, Jetpack Stef

Stef, a Happiness Engineer with Jetpack, quickly responded to my support ticket. They have confirmed that my site is not commercial, and reclassified me as a personal site. This will allow me to continue viewing the Jetpack Stats without needing to pay for an upgraded commercial account. Thank you, Stef!

Normally, I don’t think it is fair to complain about “free” stuff. Jetpack does not force ads on my content, so, as far as I can tell, using their plug-in on WordPress for personal sites truly is free. I do, however, pay for a backup service they offer, so at least they get some money out of money.

Sadly, that backup plan is no longer available, and has been replaced by a more expensive offering which I would not be able to justify for a personal site like this. Still, better to have it and not need it, than need it and not have it available.

This is not a commercial site.

Today Jetpack Stats informed me I need to upgrade to a commercial plan for this site. For some reason, I have been flagged as a commercial site. Commercial sites can use it free if they have under 5000 visitors a month which, apparently, this humble blog exceeds. That alone is surprising, since I mostly post about a 1980s Radio Shack computer, and embedded C programming ;-)

I just wanted to assure my thousands of ‘bots that scan this site regularly that I:

  1. Have no ads on this site.
  2. Do not request donations.
  3. Do not have affiliate links.

About the closest I ever get to “commercial” is when I put an Amazon link to something ;-)

I thought I’d post this so the Jetpack Support folks have something to see when/if they check out my site to verify my claim.

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…