Posted by masswerk 7/5/2025
I can't remember if this worked on the C64, but it worked on the 4016 and 4032's in our high school's computer lab.
10 REM NOTHING TO SEE HERE
20 PRINT "HELLO!"
POKE 2049,1
Run it. You'll see HELLO! LIST it and you'll continuously see line 10. If you try to LIST 20 the machine pretty much locks up.
Screen image is here:
https://jimlawless.net/images/remtrick.gif
(note that in the above image, you'll see two RUN lines ... it appears that I captured the screen as it was in mid-scroll... )
[Edit]
Coincidentally, a shifted "L" is PETSCII code 0xCC. Which is just one after the highest available token in Commodore BASIC 2.0 / V.2. (The last one being 0xCB, `GO`.) Therefor, a lookup into the keyword list will yield the terminating zero-byte, which probably causes the problem. (E.g., by defeating what was intended to be an unconditional branch instruction.)
(In BASIC 4.0 for the 40xx/80xx PETs, this is actually a valid token, namely `CONCAT`, which is expanded by LIST without further issues. Meaning, this kind of LIST protection can be broken by simply loading the program on one of the later PETs.)
I had a cursory look at it: there's no check for REM, of any kind, but there's, of course, a check for quoted strings. For any tokens, an offset count is calculated by subtracting 0x7F from the token and then a loop starts searching for set sign-bits in the keyword list, decrementing the counter each time, it finds one. If the counter is zero, we must be right at the keyword, we're looking for. – But in those cases, where we are not…
For values larger than 0xCC (shift-L), the routine actually wraps around. E.g, shift-M is listed as FOR (0x81), shift-N as NEXT (0x82), and so on. This is, because the keyword list is exactly 256 bytes long (including GO and the terminating zero-byte, like on the C64) and is inspected by an indexed load instruction. So the index register just wraps around.
(BASIC 4.0, on the other hand, has to deal with a longer keyword list anyway, so it uses a more complex method to read the list, involving a pointer. Thus it happily spills over into the list of error messages, which follows immediately after this and happens to be encoded in the same way. Therefor, it will expand any excess-tokens into error messages. I guess, this will be the same with BASIC 7, and so on, if they are anything like this.)
https://www.masswerk.at/nowgobang/2025/the-remarkable-misadv...
Variables were also 2-bytes, but ASCII. The user could enter a longer name, but only the first two characters were significant.
sign-bits type (payload)
0 0 ... floating point number (1 byte exponent, 4 bytes mantissa)
1 1 ... integer (2 bytes)
0 1 ... string (1 byte length, 2-bytes pointer to location)
1 0 ... FN function (2 bytes pointer to BASIC, 2 bytes pointer to parameter variable)
In a program (the BASIC text), though, variables names are stored in full and in plain ASCII, at whatever length of characters.