This file contains the state of PCC's script interpreter for player x. Scripts which are suspended (`Stop') end up here, including auto tasks. You should understand how PCC's interpreter works before attempting to manipulate this.
The file format consists of a header, followed by a sequence of code snippets, followed by a sequence of suspended processes.
Format of header: +0 4 BYTEs Signature 'CCvm' +4 18 BYTEs Timestamp +22 BYTE Signature 26 (^Z) +23 BYTE Format version (currently 0) +24 WORD Number of bytes following in header (currently 4) +26 WORD Turn number +28 WORD Player Id --- end of header --- +30 n BYTEs Code snippets +x n BYTEs Processes
Format of a code snippet: +0 DWORD Size of this record, not including this DWORD (0=last entry; then this is the only word in this snippet) +4 DWORD "uid" Unique identifier. This code snippet is referenced by this number. This may be any bit pattern, there's no particular rule imposed on this (actually, PCC uses raw 16:16 bit pointers here which are meaningless once PCC exits) +8 WORD Minimum argument count +10 WORD Maximum argument count +12 WORD "nalloc" Number of allocated argument names +14 WORD "code" Total size of code in bytes +16 n BYTEs "Name hint". Pascal string with a subroutine name. Can be anything without very negative consequences. The VM loader can use this, the "nalloc" field and the argument names as a hint that this code snippet originally was the specified subroutine, and if it matches the current definition, merge them; if the subroutine is not defined, this has no effect (this optimisation isn't implemented in any PCC version until now). +x n BYTEs Argument names; "nalloc" names (see `Name List' below) +x n BYTEs Code. "code" bytes, a sequence of pascal strings.
Format of a process: +0 DWORD Size of this record, not including this DWORD (0=last process) +4 WORD "sp" Stack pointer (number of inactive code blocks) +6 WORD "ctos" Context stack pointer. Specifies how many contexts this process entered, and thus must leave before terminating. The others were created by PCC before the process was started. +8 BYTE Process status. Should be 3 (suspended). +9 BYTE Process priority, 0 to 99. Low priorities run first. +10 n BYTEs Process name, pascal string (currently 45 characters max). +? n BYTEs Command sources. "sp+1" records of variable length, see below. A command source contains one or more commands that are to be executed. +? n BYTEs Contexts. Records of variable length, see below. At least "ctos" contexts, usually "ctos+2" or more.
Format of a saved command source (stack frame): +0 BYTE Type of command source (0 or 1) +1 BYTE Capabilities of this command source 0 "One" 1 "Stream" 2 "Random" Usually, type 0 command sources have the value 2 here, type 1 command sources have the value 0. +2 DWORD Instruction pointer; index of next line to be executed +6 WORD "nnam" Number of local variable names +8 WORD "nval" Number of saved local variable values. The previous two words do not have any connection, there can be more names than values or vice versa. +10 n BYTEs Local variable names, "nnam" names (see `Name List' below) +? 6N BYTEs Local variable values, "nval" records of 6 bytes each. +? n BYTEs String values of local variables. See CHARTx.CC, block 7/8, for details about the previous two fields. --- Type 0 Command Source --- +? DWORD "ip" of first line in saved code snippet +? DWORD Code snipped identifier ("uid") --- Type 1 Command Source --- +n n BYTEs Pascal string, line 0 +n n BYTEs Pascal string, line 1 (must be a single command word, may be empty)
Format of a saved context: +0 WORD Type. 0=last context, no information follows. All other contexts contain at least one (possibly unused) WORD. Values not defined here are reserved for the future; there is no way to load a saved context with an unknown number. --- Type 1 (Struc) --- +2 WORD - --- Type 2 (Global) --- +2 WORD - --- Type 3 (If/Select) --- +2 WORD Subtype; used for syntax checking 0 "Else" branch of an "If" 1 "If" branch of an "If" 2 (1.1.13+) "Case" of a "Select" --- Type 4 (With) --- +2 WORD 1 if one-line "With" --- Type 5 (Try) --- +2 WORD 1 if in "Else" branch, 0 otherwise +4 DWORD "ip" of "Try" statement + 1 +8 WORD "sp" of "Try" statement --- Type 6 (Do) --- +2 WORD - +4 DWORD "ip" of "Do" statement + 1 +8 WORD "sp" of "Do" statement +10 BYTE Type of loop/condition: 0 = "Do", 1 = "Do While", 2 = "Do Until", 3 = "For" +11 n BYTEs Condition (Pascal string) --- Type 7 (ForEach) --- +2 WORD - +4 DWORD "ip" of "Do" statement + 1 +8 WORD "sp" of "Do" statement --- Type 8 (Sub) --- +2 WORD "sp" of this subroutine (what the value of the process's "sp" field would be if the subroutine contained a single `Stop' only) --- Type 9 (Planet) --- +2 WORD Planet Id --- Type 10 (Engine) --- +2 WORD Engine Id --- Type 11 (Torpedo) --- +2 WORD Torpedo System Id --- Type 12 (Launcher) --- +2 WORD Torpedo System Id --- Type 13 (Beam) --- +2 WORD Beam Id --- Type 14 (Ship) --- +2 WORD Ship Id --- Type 15 (Hull) --- +2 WORD Hull Id --- Type 16 (Player; 1.0.8+) --- +2 WORD Player Id --- Type 17 (Minefield; 1.0.11+) --- +2 WORD Minefield Id --- Type 18 (Ion Storm; 1.0.11+) --- +2 WORD Ion storm Id --- Type 19 (Lock; 1.1.2+) --- +2 WORD 0 +4 n BYTEs Lock name, Pascal string +x n BYTEs Info text, Pascal string
Name Lists
As of PCC v1.0.7, a name list is a sequence of Pascal strings (length byte + text), with a maximum identifier length of 31 characters. Valid characters in identifiers are capital letters, digits, `$', `.' and `_'.