At the time of this revision for Color 64 v8.1a, there are notably several ML related commands and variables that are not documented from the original 8.0 manuscript, 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!
At the time of this revision for Color 64 v8.1a, there are notably several ML related commands and variables that are not documented from the original 8.0 manuscript, as well as some basic shortcuts and appear to have been introduced from the 8.1 upgrade. A lot of reverse engineering was done by comparing 8.1 code to the predecessor versions.
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
Below are some of my notes and observations of what the code was in 8.0 or 7.37, and the observed shortcuts implemented in 8.1.
Please note it is a work-in-progress and this part of the wiki gets updated frequently! Some of my observations may still be without conclusion as they are under active investigation! That said, getting to understand some of the modified BASIC can be easy. If you have the ML loaded into your system (loading and running +SHELL), you can write your own program to test out the modified BASIC by having your first line call the ML routine: SYS49923
10 SYS49923
10 SYS49923
Line 7:
Line 9:
30 etc....
30 etc....
Below are some of my observations.
----
----
Revision as of 04:48, 20 February 2026
At the time of this revision for Color 64 v8.1a, there are notably several ML related commands and variables that are not documented from the original 8.0 manuscript, as well as some basic shortcuts and appear to have been introduced from the 8.1 upgrade. A lot of reverse engineering was done by comparing 8.1 code to the predecessor versions.
Below are some of my notes and observations of what the code was in 8.0 or 7.37, and the observed shortcuts implemented in 8.1.
Please note it is a work-in-progress and this part of the wiki gets updated frequently! Some of my observations may still be without conclusion as they are under active investigation! That said, getting to understand some of the modified BASIC can be easy. If you have the ML loaded into your system (loading and running +SHELL), 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....
General Programming
Topic
Notes
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 success with this has not been consistent. Use with caution.
Topic
Notes
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 (the anchor)
@ loop condition – goes back to the last anchor
@[x] jump back if x is non-zero
“]” is the Color 64 BASIC conditional action delimiter: it separates an IF test from the statement list executed when the test is true.
This is heavily used with status:
@[SR] means: if SR<>0 then jump back to the last [ anchor.
If SR is 0, it falls through and the loop ends naturally.
So you will see in numerous places:
do read / set SR=ST
@[SR] to continue while status says “keep going”
Topic
Notes
"THEN" with IF
All Main Overlays
8.0
8.1
Conclusion: “then” statements are not required for “if/then” – if <condition> <action> is legal in most cases.
Topic
Notes
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
Notes
@
√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
Notes
[var$]
√bbs.msgs
Example
8.0
8.1
1
Conclusion: Can serve as an empty variable check (null)
ML Commands
Topic
Notes
.8
All Main Overlays
.8 - Session/Input Poll)
Previously documented in 8.0 documentation as "Equivalent of the "%" command…", this appears to be rewritten in version 8.1 - and is particularly noticeable in bbs.msgs where comparing the two show that .8 has replaced the gosub110 routine (which in 7.37 called sysc(4) or in 8.0, .00.
7.37
8.1
and routine at 110....
No use of routine at 110...
Polls for typed input (non-blocking, local or remote), normalizes transient input-status states, and refreshes session status. Typically used inside scrolling output/file display loops and before slow operations. Side effects include updating P (0 OK, 1 user abort, 255 carrier lost/timeout) and possibly the same underlying status/character registers used by .00.
While further testing is required, theoretically this should fully replace use of gosub110
Topic
Notes
.9
All Main Overlays
Previously documented in 8.0 documentation as a "do not use" command that replaces "&" function, this appears to be repurposed for single key command input replacing the traditional "gosub110" routine.
.9 – Single-Key Command Input Poll
Overview
The .9 command polls for a single keypress and stores the result into the BASIC string variable A$. It is used at the command prompt to capture one-character command input from either the local keyboard or remote modem connection.
Previous iterations of Color 64 used gosub110 in the same areas.
When a key is pressed:
A$ is set to the key pressed
The character is stored in high-bit PETSCII format
Example:
Pressing "X" → ASC(A$)=216
Pressing "O" → ASC(A$)=207
(Standard ASCII value + 128)
When no key is pressed:
A$="" (empty string)
The command does not block execution
Examples (bbs.msgs):
Bare Poll
110 .9:RETURN
995 .9:IF A$<>NU$ OR P=1 THEN 995:RETURN (loop until a key appears or abort)
Filtered Keys
1020 .9,"YN":RETURN (only accept Y/N)
3715 .9,"12345"+CR$:IF P ... (menu choices plus Enter)
Space-as-abort convention
9132 .9:IF A$=" " THEN P=1
(and several more spots do the same)
So .9 is essentially the modern ML command that replaced the old sysc(4) “get typed character” behavior, with a nice extra: it can be told “only accept these characters”.
Topic
Notes
.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
Category: ML Command
Seen in: All Main Overlays (prompt printing routine)
Overview
The .36 command is called immediately after printing the command prompt
and just before entering the main command input polling loop (.9).
In testing within the live BBS environment, removing .36 did not alter
normal command prompt behavior, local keyboard input, or remote input handling.
This suggests .36 is either redundant in v8.1, reserved for edge cases,
or included for compatibility with earlier ML builds.
Observed Call Pattern
Prompt is printed (PETSCII-dependent)
.36 executes unconditionally
Return into the .9 command polling loop
Testing Notes
With .36 present:
Pressing a command key results in A$ being set to high-bit PETSCII
P variable functions normal (remains 0) at command prompt operations
With .36 removed:
No visible change under normal BBS operation
.9 functioned normally.
Working Hypothesis
.36 likely performs a defensive reset of internal prompt/input state
(e.g., clearing a latch, normalizing editor mode, or handling rare typeahead /
carrier-transition conditions). No definitive functional effect has been
confirmed under standard test conditions.
Summary
.36 is executed as part of the prompt cycle in v8.1 but does not appear
necessary for normal command entry. Further testing under stress conditions
(typeahead flooding, carrier transitions, mode switching) may reveal its purpose.
Topic
Notes
.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):
Message Relink Commands in v8.1
Command
Purpose
.38
Initialize / bind relink iterator operands
.39
Perform iterator scan step
.40
Advance iterator (skip / continue)
.41
Finalize relink process
.38 – Relink Iterator Initialization (v8.1)
The .38 command was introduced in Color64 v8.1 as part of the internal message relinking system and is the entry point of the entire process. It does not perform file I/O directly and does not read or write messages itself. Instead, it initializes and binds internal machine-language structures used by the message relinking iterator.
It is designed to be used as the first step in a command sequence:
.38 → .39 → .40 / .41
This sequence replaces the more BASIC-driven record scanning logic found in v8.0.
What .38 Does
Binds specific BASIC variables/arrays to ML-side descriptors
Registers operands for the relink iterator
Initializes scratch registers used by subsequent .39 operations
Prepares the ML environment for scanning and linking old message records
In BBS.MSGS, this binding typically associates:
Slot 0 → MN (message number)
Slot 1 → MR% (message read flags array)
The ML iterator then uses internal scratch registers such as:
;0K
;1K
;0F
These are later examined by BASIC to determine loop control and branching.
In v8.0, message scanning and linking logic was performed directly in BASIC, including character comparisons and explicit loop control.
In v8.1, this logic was moved into machine language for speed and structural cleanliness. BASIC now acts primarily as a decision layer while ML handles the iteration mechanics.
Important Notes
.38 must precede .39 in relink routines
.38 does not itself advance or scan records
It prepares the ML environment used by the iterator
It is not a general-purpose file command
It is specific to the message relinking system
Summary
The .38 command initializes the v8.1 message relink iterator by binding
BASIC variables to ML-side structures. It marks the transition from the
BASIC-driven record scanning model of v8.0 to the ML-driven iterator model of
v8.1.
It should be understood as a setup command rather than an action command.
ML Variables
Topic
Notes
!8
Wrap/Width Threshold
The !8 was originally documented in 8.0 "reserved for future use" but is now utilized in some sections where it is used to check if a string is less then the value of !8 and decides how to print the string based on that check.
Example: if len(a$)<!8 then #:£$
In the example above, if a line is shorter than !8, they force an explicit newline behavior; if it’s longer, they let natural wrapping do the work.