Undocumented 8.1 commands

From Color 64 BBS Wiki
Revision as of 21:10, 18 February 2026 by Admin (talk | contribs)

At the time of this revision for Color 64 v8.1a, there are notably several ML related commands and variables that are not documented as well as some basic shortcuts and appear to have been introduced from the 8.1 upgrade. I find that comparing 8.0 code with 8.1 helps you along in figuring out what these undocumented items perform. Below are some of my notes and observations of what the code was in 8.0 and the observed shortcuts implemented in 8.1 Please note it is a work-in-progress and I don’t have all the answers (yet), so some of this is just “observation” without any conclusion!

Getting to understand some of the modified BASIC can be easy. If you have the ML loaded into your system, you can write your own program to test out the modified BASIC by having your first line call the ML routine: SYS49923

10 SYS49923
20 #"Test of program"
30 etc....

Below are some of my observations.

Topic Found in
Simple Addition All overlays

Color 64 allows simple addition without using < var >=< same var >+< value >

So "a=a+12" can alternately just be: "a+12". This only works with numbers (not strings) and other times, this just fails completely. Buyer beware.

Topic Found in
Branch Shortcuts √bbs.init
Example 8.0 8.1
1
2
3
4

Conclusion: “[“ and “@” are used for loops with “[“ being the starting position and “@” being the condition that will cause the function to return to the starting point of the loop. Also note in line 8220 how the “RETURN” statement moved from line 8230 up into the 8220 loop in version 8.1 (example 2), indicating that it will execute the return if a$ <> “” and a$ <> home key.

[ starts loop
@ loop condition – goes back to bracket when used after “@”, consider an “ELSE” statement in this loop (example 2)
] breaks loop condition (Example 3)
A break “]” can occur as part of an IF statement to exit prior to “@” for loop (example 4)
Topic Found in
Use of "THEN" in IF all
Example 8.0 8.1
1

Conclusion: “then” statements are not required for “if/then” – if <condition> <action> is legal in most cases.

Topic Found in
.36 √bbs.init
Example 8.0 8.1
1

Conclusion: Undetermined, although notice line in 8.0 version that line 13645 has been dropped for the 8.1 variant. This command only occurs on this line in the overlays as part of the command prompt. When I dropped everything in line 13640 and just had “.36:return”, there was no box printed (of course), but the command entry functioned normally. This was also true if I just omitted everything except “return” – so I’m not sure what “.36” brings to the table.

Topic Found in
.31 and !55 √bbs.msgs
Example 8.0 8.1
1

Conclusion: .31 – Message-Aware Disk Input (Version 8.1)

Earlier documentation listed the ML command .31 as "not used." Analysis of Version 8.1 confirms this is incorrect. In Color 64 v8.1, the .31 command is actively used within message-handling overlays (notably BBS.MSGS) and functions as a specialized form of disk input. It replaces the earlier .01 disk input command used in Version 8.0 when scanning and reading private messages.

Comparison: Version 8.0 vs Version 8.1

8.0 8.1
Message scanning used: .01

After each read, BASIC code manually checked for a message delimiter: IF @0 = CHR$(14) THEN .... The byte {0E} (CHR$(14)) acted as the message record separator. When this character was encountered, the system incremented or decremented message counters, control flow moved to the next message record, and the loop continued scanning until completion. The delimiter (end of message) detection was handled explicitly in BASIC.

In Version 8.1, .01 is replaced in message routines by: .31. The .31 command performs the disk input operation and internally detects the message delimiter. Instead of BASIC checking @0 = CHR$(14), Version 8.1 uses the ML variable IF !55 THEN .... When !55 becomes non-zero, the system has reached the end of the current message record, message counters are updated, and control moves to the next message or exits the loop. Delimiter detection is now handled inside the ML routine rather than in BASIC.

!55 – Message Record Delimiter Flag !55 is an ML variable introduced in Version 8.1 that serves as a message record boundary flag. It is set automatically by .31 when the message delimiter byte (previously tested as CHR$(14) in Version 8.0) is encountered.

!55 = 0 → No delimiter encountered
!55 ≠ 0 → End of message record reached

When !55 is detected:

  • The current message scan loop updates counters
  • The system transitions to the next message record
  • Display or processing routines advance accordingly
Topic Found in
.38 / .39 / .40 / .41 and “;” variables √bbs.msgs
Example 8.0 8.1
1 (current message vs high message):
(current message vs high message):
2 (reading message):
(reading message):
3 (storing message):
(storing message):

Observation (no conclusion): This is one of the more intriguing finds and it’s a hot mess – lines 3140, 3555 and 1525 are obviously the topics of interest. I can’t tell you what’s going on here, but here are some observations from my research:

  • Example 1 is very close to Example 2, so read on….
  • Example 2 is reading a message after the user has selected a message number.
From 8.0, m=last message read, mn(.) is our message numbers array, mr%(m) tracks messages that have been read, and mn (not arrayed) is undocumented, but suspect it is “current message number”.
  • Breaking down line 3140:
You can see the loop function “[“, “@” and “]” replacing our for-next in line 3140, and in same line variable “m” is being decremented, replacing the “step -1”. “@m” appears to be our “next m” of the for next loop replacement.
Our preparation for the loop is present:
8.0 statement for m=mn(.) can be tied to 8.1 statement m=mn(.).
I suggest the following matches from line 3140 comparison:
  • 8.0 statement ifmn(m)>ithennext = 8.1 statements if;0f<=I]£ and @m
  • 8.0 statement mr%(m)=. = 8.1 statement ;1k=.
  • both of these statements are occurring inside the loop; and that covers all of the original 8.0 line of 3140.
So what are the 8.1 statements .38,0mn,1mr% and .39,fm,km doing before we enter the loop? There is no equivalent statement I can derive from 8.0. Printing the value of these parameters did not provide any insight either, although we know what mn and mr% are, and fm – if being used correctly – is word-wrap. Variable km is undefined and it is not set anywhere in the basic code of √bbs.msgs.
  • Example 3 is storing a new message and updating the message links
It appears the 8.1 version of line 1525 uses “old to new” assignments to replace the incrementation we see in the 8.0 version. The 8.1 statement .40,fgkl is a mystery, but appears to be a new ML routine to use the new assignments of the variables f, g, k, and l that occurred on the same line.
  • Examples 1 & 2 appear to use different subject parameter for parameter #2 in the .38 function. Example 1 shows .38 receiving last message read as parameter 1 and category as parameter 2. Example 2 shows message number as parameter 1 and .38 is taking two parameters: “0mr%” and “1ca%” separated by a comma
Topic Found in
if...£ √bbs.msgs
Example 8.0 8.1
1

Observation: Observe the 8.1 authors reversed the checks in variable comparisons as the conditions, with end-result being the same.

Conclusion: Serves as an “not” function “(lv is not less than cm%(2,2) and lv not less than cm%(29,2) and fr does not equal 1, then print (P)rivate)”

Another example:


Topic Found in
@ √bbs.msgs
Example 8.0 8.1
1

Conclusion: Seems to serve as an “if” keyword - but testing this theory in a traditional sense resulted in a syntax error.

Topic Found in
[var$] √bbs.msgs
Example 8.0 8.1
1

Conclusion: Can serve as an empty variable check (null)

Topic Found in
.32 √bbs.msgs

Researching / Unknown