MediaWiki:Sitenotice:
2024-03-02: The wiki ran out of disk space, so things were not working. This has been resolved by adding another 5GB of quota ;-) Thanks to Tim Lindner for reporting the issues. 2020-05-17: If a page gives you an error about some revision not being found, just EDIT the page and the old page should appear in the editor. If it does, just SAVE that and the page should be restored. OS-9 Al (talk) 12:22, 17 May 2020 (CDT)

The Structure of I-Code

From CoCopedia - The Tandy/Radio Shack Color Computer Wiki
Revision as of 20:28, 18 September 2013 by Wayne (talk | contribs) (→‎Terms Used)
Jump to navigation Jump to search

The 'I' in I-Code stands for Intermediate. Intermediate code is code that is a step between interpreted source statements and fully compiled machine code. Typically, intermediate code uses tokens to represent the instructions to be executed. Basic09 I-Code goes a step further by re-arranging the source code instructions in post-fix notation (also known as Reverse Polish Notation) order.

The tokens used by Basic09 are a single byte ranging from $00 to $FF. See I-Code Token List

Terms Used

Vector 1 Dimensional Array
Table 2 Dimensional Array
Matrix 3 Dimensional Array
Variable Declaration Table (VDT) Symbol Table
Data Storage Allocation Table (DSAT) Definition Area

The terms Vector, Table and Matrix, as used to describe the arrays, is defined in the Microware OS-9 Basic User Manual (for OS-9/68000, (c)1991), Chapter 3: Program Construction: Complex Data Types and Subroutines on page 3-1.

Module Format

Basic09 I-Code modules use the same module format as any other OS-9 executable module. However, I-Code modules include optional header extensions not included in other types of memory modules. They also include two very important tables specific to I-Code modules.

Modules are divided into the following sections:

Module Header

Description Size Note
Module Header Space (Sync Bytes) INTEGER Value always $87CD
Total Procedure Block Size INTEGER Total size of the module, including CRC and header
Module Name Offset INTEGER Offset address in the header of the Procedure Name Beginning
Module Type/Language BYTE Value always $22; Sub-Routine/Basic09 I-Code
Module Attributes/Revision BYTE Value always $81; Re-Entrant,Re-Locatable Object/Revision=1
Module Header Parity BYTE Last required module header entry; optional header extensions follow
I-Code Area Address INTEGER Offset address of the I-Code instructions
Runtime Variable Storage Size INTEGER Total data memory size for the module
Symbol Table Address INTEGER Offset address of the VDT
Description Area Address INTEGER Offset address of the DSAT
Procedure Link Storage Offset INTEGER Beginning of Named Subroutine Storage in Data Memory
First Data Statement Address INTEGER Offset address of the first element of the first data statement
First Executable Statement Address INTEGER Value always $0000; (Unused, Possible association: <dex> token. See 2)
Procedure Status BYTE Value always $80; (I do not know what this BYTE is used for.)
Procedure Name Size BYTE
Procedure Name Beginning Procedure Name Size BYTEs Last character hi-bit set
Edition Number BYTE Always the first byte after the Module Name. This BYTE is actually the first byte of I-Code, at the I-Code Area Address location, and not part of the header. See 1

NOTES


1: The OS-9 Level II Manual describes the Edition byte in Chapter 6. System Command Descriptions, under the Ident command on page 6-52,53.
The OS-9 Level I Manual Set includes this information in the OS9 Commands Manual, Chapter 6. System Command Descriptions, Ident command, page 87.
2: the <dex> token is $3C, and is defined in the Basic09 header file:

  T.DEXC rmb 1 Direct execution

There is also a Basic09 error:

  48: Unimplemented routine

While I have never run into this error in any procedure I have written or decoded, it still exists. The token is actually unused. Aaron Wolfe and I experimented with it, embedding the token in a source file, and the test procedure returned the 48 error when it was loaded. Is it possible that Basic09 originally had code that allowed its developers to insert assembly language instructions directly into the I-Code? I can see where it would have been useful, and I can see where that code would be in comments in the original source, if the authors didn't want that included in the final compile.

I-Code Area

This is where all of your instruction statements are stored in tokenized post-fix notation form. While there is no requirement to do so, it is typical to see this area terminated with a END ($39) token followed by a line termination token ($3F).

Basic09 allows you to place TYPE, DIM and PARAM statements anywhere in the source code. When Basic09 loads your source, it immediately converts the source to tokenized form. In doing so, it compiles a complete list of your program variables as it loads. It also compiles a complete list of all line references. Line references are not the numbers you place at the beginning of a line. This list is created from all GOTO ($20) and GOSUB ($22) (including ON ERROR GOTO, and ON <expr> GOTO/GOSUB), RESTORE <lref> ($31) and IF-THEN <lref> ($10-$45) statements. In addition, there are internal offset branch tokens, including invisible goto (<ivgt> $55), the line reference token ($3B), ELSE ($11), ENDWHILE ($16) and ENDLOOP ($1A).

Description Area

This is the first of the two variable-related tables in I-Code modules. In reality, this section contains the shape data for all variables more complex than a simple atomic type. The form the shape data takes is specific to the type of variable being described. The most simple form is:

offset - size (both INT-size)

Offset is the data memory location of the variable, and size is the length of the variable. This form is used, by itself, to describe non-array STRING and record variables. All other entries (except TYPE shape data) begin with these two fields, and add extra fields to describe the variable. These variables are the array variables, and include the following fields (all INT-size):

  • first element size (all arrays)
  • second element size (all table and matrix arrays)
  • third element size (all matrix arrays)

The above are actually added in reverse order:

offset - size - elem3 - elem2 - elem1[ - elemSize]
  • element length (all STRING and record arrays)

TYPE statement data is different. First, all complex data forms included in the TYPE are listed immediately before the shape data for the TYPE. In these cases, the offset is not a data memory address, but the offset within the record for that variable. The form the TYPE shape data takes is as follows:

  size (INT); unknown use (INT or 2 BYTEs); first field (single BYTE); second field (INT); ... <nth> field (INT)

TYPEs within TYPEs adds a new level of complexity. Before the shape data that includes a field DIM'd as a record, the shape data for that record TYPE is defined. as well as any other complex variables defined in that TYPE occurring before its shape data.

At the end of this table is another "3-byte" structure. However, this one is reversed, so it is <INT>-<BYTE>, and each can be viewed as separate from the other. The INT is the Total Program Variables count. This number includes all DIM'd, PARAM'd and TYPE'd variable names. Yes, TYPE REG= means REG is counted as a variable. This number also includes all variables defined by use.

The BYTE, in every module I have seen except one, holds the value $03. In the one case, it held the value $04. I no longer have the module that contained $04, and I have never understood what this byte is used for. It is the final byte before the beginning of the Symbol Table.

Symbol Table

This is the second of the two variable-related tables in I-Code modules. The first thing you will notice is that this table is almost entirely 3-byte structures, similar to the ones found in the I-Code area. The difference here is the number of different tokens for defining variables according to their atomic type, as well as STRINGs, records and arrays. Parameter variables are listed here, following the program variables, and after that comes the named subroutine (external procedure/object-code subroutine) list.

Sub-routine entries begin with the $A0 token, followed by the data memory offset of the pointer to that subroutine, and the text of the name of the subroutine (last character hi-bit set, same as the module name in the header of the module). The Procedure Link Storage Offset in the header points to the first memory location that holds the pointer to the first subroutine named in this section of the list. For all other VDT tokens, see the Symbol Table Tokens.

The offset field in the program variables and parameter variables portion of the list points to one of three places.

  • In all atomic record field entries ($40-$43) the offset is the position within the record of that field. The atomic type determines the size.
  • In all atomic variables ($60-$63), the offset is the data memory location of that variable, and the size is determined by the type.
  • In all atomic parameter variables ($80-$83), the offset is the data memory location of that variable, and the size is four BYTEs.
  • In all other variable types, the offset is relative to the beginning of the DSAT.

The data size for each parameter variable, whether atomic or not, is four BYTEs. That is the difference between one parameter's data memory address and the next one. The DSAT contains the shape data for the more complex variables, but the data memory pointer in a called procedure is a 4-byte pointer.

Note: In a perfect world these three sections of the VDT would be completely segregated. However, this is not the case in the real world. You will see times when there are program variables occurring within the parameter and subroutine sections. I think this is due to repeated edit/save/pack sessions. I believe that a minor change will not result in rebuilding the entire list, especially if you do not reload the source after saving changes.

CRC

All OS-9 memory modules end with a 3-byte CRC. I have not seen a utility for re-calculating a module's CRC.

Instruction I-Code

In this section I will describe the various structures used in Basic09 coding, including the looping constructs, conditional statements, and the use of literals (constants).

Internal Structures

As you have seen, I-Code makes use of 3-byte structures for variable references. It uses them as well for branch references (including line references). They use the form:

token - offset

where token is any valid Basic09 branch or variable token, and offset is a INTEGER-size value. All addressing in I-Code is relative. Branch references are relative to the beginning of the I-Code area, and variable reference offsets are relative to one of the following:

  • BYTE, INTEGER, REAL and BOOLEAN references (token values $80-$83): data memory offset relative to the beginning of data memory.
  • STRING references (token value $84): DSAT offset relative to the beginning of the Description area.
  • all other token values in the I-Code area: VDT offset relative to the beginning of the Symbol Table.

Files

Data Memory Map

  0                  $15|$16
 +----------------------+-----------------+--------------+--------------------+
 |reserved by RunB      |program variables|parameter list|named procedure list|
 +----------------------+-----------------+--------------+--------------------+

The first $16 (22) bytes of the data space is reserved for use by RunB. Following this are the program variables, the parameter list, and the named procedure list.

Structures

FOR/NEXT

The FOR/NEXT loop structure is the most complex in terms of I-Code. It contains the most fields of any other loop structure in Basic09.

FOR R0122= 1 TO 8 \
13 82 07D3 53 8D 01 CB 46 07D8 8D 08 CB 55 006A 3E
FOR R0122 = <bc> 1 <flt1> TO <bc> 8 <flt1> <ivgt> \

13 is the FOR token
82 is the REAL type token
07D3 is the data memory offset for a REAL variable named R0122, which occupies 5 bytes beginning at that location
53 is the = assignment operator token
8D is the <bc> (byte constant) token, and is associated to the following numeric value
01 is the value 1
CB is the <flt1> (float top of stack) token
46 is the TO token
07D8 is the data memory offset for a temporary variable used to store the following value
8D is the <bc> (byte constant) token, and is associated to the following numeric value
08 is the value 8
CB is the <flt1> (float top of stack) token
55 is the <ivgt> (invisible goto) token
006A is the module offset to branch to when the condition fails
3E is the \ instruction terminator. This character allows stacking of mutiple statements on a single line in the source code. Many times, these occur because the author included line comments, such as \REM populate array. Usually, this will be the <eol> (3F) terminator

NEXT R0122
14 02 07D3 07D8 0000 004C 3F
NEXT R0122 TO STEP <ivgt> <eol>

14 is the NEXT token
02 determines REAL or INTEGER, with or without a STEP value.

00 INTEGER
01 INTEGER w/STEP
02 REAL
03 REAL w/STEP

07D3 is the data memory address for R0122
07D8 is the TO variable
0000 is the STEP variable, if included in the FOR statement. In every FOR loop that does not include a STEP value, this integer is 0
004C <ivgt> pointing to the beginning of the first instruction within the loop. Note the lack of a $55 token. This is the only condition where a <ivgt> does not have the token
3F is the <eol> (end of instruction/line) token

WHILE/ENDWHILE

WHILE loops test an expression as TRUE or FALSE at the beginning of the loop. As a result, these loops may be skipped if the condition is already FALSE.

WHILE NOT(EOF(#B0028)) DO
15 80 0329 BE CD 55 0DE7 48 3F
WHILE B0028 EOF() NOT() <ivgt> DO <eol>

15 is the WHILE token
80 is the BYTE type token
0329 is the data memory address of a variable named B0028
BE is the EOF() function token
CD is the NOT() function token
55 is the <ivgt> token
0DE7 is the offset to branch to when the condition fails
48 is the DO token
3F is the <eol> token

ENDWHILE
16 0CBF 3F
ENDWHILE <offset> <eol>

16 is the ENDWHILE token
0CBF is the offset address of the WHILE statement
3F is the <eol> token

REPEAT/UNTIL

REPEAT loops will always be executed at least once, since the test for a TRUE/FALSE condition occurs at the bottom of the loop.

REPEAT
17 3F
REPEAT <eol>

17 is the REPEAT token
3F is the <eol> token

UNTIL MID$(S0107,I0051,1)="/" OR I0051=0
18 84 01FF 81 0378 8D 01 C0 90 2F FF DF 81 0378 8D 00 DD D1 55 102C 3F
UNTIL S0107 I0051 <bc> 1 MID$(,,) "/" = I0051 <bc> 0 = OR <ivgt> <eol>

18 is the UNTIL token
84 is the STRING type token
01FF is the data memory address of a variable named S0107
81 is the INTEGER type token
0378 is the data memory address of a variable named I0051
8D is the <bc> token
01 is the value 1
C0 is the MID$ function token
90 is the " beginning-of-string token
2F is the / character
FF is the " end-of-string token
DF is the = string comparison operator token
81 is the INTEGER type token
0378 is the data memory address of a variable named I0051
8D is the <bc> token
00 is the value 0
DD is the = byte/integer comparison operator token
D1 is the OR boolean operator token
55 is the <ivgt> token
102C' is the offset address of the first instruction inside the loop
3F is the <eol> token

LOOP/ENDLOOP

This is the most simple loop structure in Basic09. The EXITIF-THEN/ENDEXIT construct is the only way to exit this loop.

LOOP
19 3F
LOOP <eol>

19 is the LOOP token
3F is the <eol> token

ENDLOOP
1A 0BC6 3F
ENDLOOP <offset> <eol>

1A is the ENDLOOP token
0BC6 is the offset address of the first instruction inside the loop
3F is the <eol> token

Conditional

IF-THEN <lref>

This form of IF/THEN does not use a ENDIF token.

IF I0040=0 THEN 20
10 81 035E 8D 00 DD 55 0395 45 3B 05E1 3F
IF I0040 <bc> 0 = <ivgt> THEN <blref> 20 <eol>

10 is the IF token
81 is the INTEGER type token
035E is the data memory address of the variable I0040
8D is the <bc> token
00 is the value 0
DD is the = byte/integer comparison operator token
55 is the <ivgt> token
0395 is the offset address to branch to if the condition fails, the next instruction
45 is the THEN token
3B is the <blref> token
05E1 is the offset address inferred by the reference 20 and is where execution will continue if the condition is TRUE
3F is the <eol> token

IF-THEN/ENDIF
IF LEFT$(S0098,2)="-D" THEN \
10 84 01CF 8D 02 C1 90 2D44 FF DF 55 03DD 45 3E
IF S0098 <bc> 2 LEFT$(,) "-D" = <ivgt> THEN <eol>

10 is the IF token
84 is the STRING type token
01CF is the DSAT offset of the variable S0098
8D is the <bc> token
02 is the value 2
C1 is the LEFT$ token
90 is the beginning " token
2D44 is the characters -D
FF is the ending " token
DF is the = string comparison operator
55 is the <ivgt> token
03DD is the offset address to branch to if the condition fails
45 is the THEN token
3E is the \ token

ENDIF
12 3F
ENDIF <eol>

12 is the ENDIF token
3F is the <eol> token

IF-THEN/ELSE/ENDIF
IF LEFT$(S0098,3)="-RR" THEN
10 84 01CF 8D 03 C1 90 2D5252 FF DF 55 0463 45 3F
IF S0098 <bc> 3 LEFT$(,) "-RR" = <ivgt> THEN <eol>

10 is the IF token
84 is the STRING type token
01CF is the DSAT offset of the variable S0098
8D is the <bc> token
03 is the value 3
C1 is the LEFT$ token
90 is the beginning " token
2D5252 is the characters -RR
FF is the ending " token
DF is the = string comparison operator
55 is the <ivgt> token
0463 is the offset address to branch to if the condition fails, the first instruction inside the ELSE clause
45 is the THEN token
3F is the <eol> token

ELSE
11 046B 3F
ELSE <offset> <eol>

11 is the ELSE token
046B is the offset address of the first instruction after the ENDIF and <eol> tokens)
3F is the <eol> token

ENDIF
12 3F
ENDIF <eol>

12 is the ENDIF token
3F is the <eol> token

EXITIF-THEN/ENDEXIT
EXITIF IA0064(I0045,R0125)=0 THEN
1B 81 0368 82 2952 C8 87 00E4 8D 00 DD 55 1CA2 45 3F
EXITIF I0045 R0125 <flt1> IA0064 <bc> 0 = <ivgt> THEN <eol>
ENDEXIT
1C 1F09 3F
ENDEXIT <offset> <eol>

Literals

Basic09 does not have named constants.* Because of this, all "constants" in Basic09 are of the literal variety. If you want to use variables as constants, you may do so, but it is up to you to ensure that the variables being used as constants are not being modified. To help with this, the recommended form of variable naming is to use a lowercase 'c' or a underscore '_' as the first character of the variable name (e.g. cMyConstant or cMYCONSTANT or _myConstant or _MYCONSTANT).

Type Token Value
BYTE $8D numeric literal from 0 to 255/-128 to 127
INTEGER $8E numeric literal from -32768 to 32767
REAL $8F numeric literal in the range of a Basic09 REAL
Hexadecimal Integer $91 hexadecimal value from $0000 to $FFFF
BOOLEAN $BC = TRUE
$BD = FALSE
STRING $90 = beginning bound of string string of text
$FF = ending bound of string

* Basic09 has one named constant: PI. It is listed with the functions, but the descriptions in the manual say "[Represents ]the constant 3.14159265" (Level 1:Chapter 8. Expressions, Operators, and Functions:p. 54) (Level 2:Chapter 7. Expressions, Operators, and Functions:p. 7-8)

About GOTO, GOSUB and <lref> tokens

There are two types of these identified in the Basic09 header. They are identified as bound and unbound.

GOTO GOSUB <lref>
Unbound 1F 21 3A
Bound 20 22 3B

The bound versions are the ones that occur in packed I-Code. I believe the unbound versions are used when Basic09 loads your source into the workspace and converts it to I-Code initially. I think it works something like this:

As Basic09 loads the source, it is replacing all keywords, function names and other items with tokens. As it comes across GOTO, GOSUB and <lref> identifiers (THEN <lnum>, RESTORE <lnum>, ON ERROR GOTO <lnum>, ON <expr> GOTO/GOSUB <lnums>), it searches the table it creates to hold branch references. If the line number has already been identified (existed at the beginning of a line and the address was resolved), that one is skipped and the identifier is flagged with the bound token. If that line number has not yet occurred in the source, then that identifier is flagged with the unbound token until that line number occurs at the beginning of a source statement, at which time the identifier is flagged with the bound token. Any identifiers not resolved when the source is loaded results in an error.

This is why the line number at the beginning of a line can disappear from your I-Code. Without an identifier to point to it, that reference does not exist in packed I-Code.

File Access Mode Tokens

READ+WRITE = UPDATE

80 DIR
01 READ 81 READ+DIR
02 WRITE 82 WRITE+DIR
03 UPDATE 83 UPDATE+DIR
04 EXEC 84 EXEC+DIR
05 READ+EXEC 85 READ+EXEC+DIR
06 WRITE+EXEC 86 WRITE+EXEC+DIR
07 UPDATE+EXEC 87 UPDATE+EXEC+DIR

I-Code Instruction Variable Tokens

I have never liked the usage of MIRROR in this instance. I have no better way to describe these tokens at this time. I referred to them as mirror tokens, because in some instances they act as a duplicate of the variable, such as in the case of a:=a+1. Both 'a' variables refer to the same variable, but in the I-Code, each has a separate token, and with the exception of 80-84 (in the instruction area) point to the VDT. 80-83 in the instruction area point to data memory addresses, and 84 points to the DSAT.

VARIABLE FIELD PARAMETER
TYPE TOKEN MIRROR TOKEN MIRROR TOKEN MIRROR
BYTE 80 F2 F6 89 85 F2
INTEGER 81 F2 F6 89 85 F2
REAL 82 F2 F6 89 85 F2
BOOLEAN 83 F2 F6 89 85 F2
STRING 84 F2 F6 89 85 F2
RECORD 85 F2 F6 89 85 F2
VECTOR 85/86 F3 F7 8A 85/86 F3
TABLE 85/87 F4 F8 8B 85/87 F4
MATRIX 85/88 F5 F9 8C 85/88 F5

Symbol Table Tokens

SIM = Simple   VEC = Vector   TAB = Table   MAT = Matrix
FIELD VARIABLE PARAMETER
TYPE SIM VEC TAB MAT SIM VEC TAB MAT SIM VEC TAB MAT
BYTE 40 48 50 58 60 68 70 78 80 88 90 98
INTEGER 41 49 51 59 61 69 71 79 81 89 91 99
REAL 42 4A 52 5A 62 6A 72 7A 82 8A 92 9A
BOOLEAN 43 4B 53 5B 63 6B 73 7B 83 8B 93 9B
STRING 44 4C 54 5C 64 6C 74 7C 84 8C 94 9C
RECORD 45 4D 55 5D 65 6D 75 7D 85 8D 95 9D

Keyword Tokens

04 DATA 05 STOP 06 BYE 39 END
07 TRON 08 TROFF 09 PAUSE 0A DEG 0B RAD
0C RETURN 0D LET 0F POKE
10 IF 11 ELSE 12 ENDIF
13 FOR 14 NEXT 15 WHILE 16 ENDWHILE
17 REPEAT 18 UNTIL 19 LOOP 1A ENDLOOP
1B EXITIF 1C ENDEXIT
1D ON 1E ERROR 20 GOTO 22 GOSUB
23 RUN 24 KILL 25 INPUT 26 PRINT
27 CHD 28 CHX
29 CREATE 2A OPEN 2B SEEK 2C READ 2D WRITE
2E GET 2F PUT 30 CLOSE 32 DELETE 31 RESTORE
33 CHAIN 34 SHELL 35 BASE 0 36 BASE 1

Secondary Keyword Tokens

45 THEN
46 TO
47 STEP
48 DO
49 USING

Punctuation Tokens

4B , comma used in DIM and PARAM statements and ON <expr> GOTO/GOSUB statements
4C : colon used in DIM, TYPE and PARAM statements to define atomic type
4D ( open parenthesis used in RUN statements
4E ) close parenthesis used in RUN statements
51 ; semi-colon used in TYPE statements to concatenate fields of different types

String Length Value Tokens

These are used to determine string length in DIM, TYPE and PARAM statements.

4F [ open bracket
50 ] close bracket

Assignment Operator Tokens

52 := colon-equals PASCAL-style assignment operator
53 = equals normal assignment operator

File Mode and Path Operator Tokens

4A : colon mode
54 # hash file path

Internal Tokens

0E <cva> complex variable assignment
3A <ulref> unbound line reference
3B <blref> bound line reference
3E \ backslash end-of-instruction, continue line
3F <eol> end-of-line
55 <ivgt> invisible goto
C8 <fix1> fix top of stack
C9 <fix2> fix second on stack
CA <fix3> fix third on stack
CB <flt1> float top of stack
CC <flt2> float second on stack

Numeric Function Tokens

PI is actually a constant. INT() has two forms (AC and AD). Note the difference in the way the level 1 and level 2 manuals define the function:

Level 1:Chapter 8. Expressions, Operators, and Functions:p 54:
INT(<num>) truncates all digits to the right of the decimal point of a REAL <num>.
Level 2:Chapter 7. Expressions, Operators, and Functions:p 7-8:
INT Calculates the largest whole number less than or equal to the specified number.

Because of this, I am not sure why there are two versions. Further investigation must be done.

In the following list, the 98,9D and A6 tokens are BYTE/INTEGER versions, and 99,9E and A7 tokens are REAL versions. There are other tokens that reflect this division, but more investigation needs to be done to determine the specifics.

97 ERR() 98 MOD() 99 MOD() 9A RND()
9B PI 9D SGN() 9E SGN() 9F SIN()
A0 COS() A1 TAN() A2 ASN() A3 ACS() A4 ATN()
A5 EXP() A6 ABS() A7 ABS() A8 LOG() A9 LOG10()
AA SQRT() AB SQR() AC INT() AD INT() AE FIX()
AF FIX() B0 FLOAT() B1 FLOAT() B2 SQ() B3 SQ()

Screen/Print Function Tokens

96 POS()
C7 TAB()

File and Other Function Tokens

ADDR() and SIZE() are the only two functions that have two tokens each. In I-Code, the second token appears in the code before the address of the item to be used as the argument to the function, and the function token appears after it.

reg.x:=ADDR(optionPacket)
0E 85 000C F6 0006 52 93 F2 0015 92 3F
<cva> reg .x := <addr> optionPacket ADDR() <eol>

0E = cva (complex variable assignment)
85 000C = reg
F6 0006 = .x
52 = := (assignment operator)
93 = <addr>
F2 0015 = optionPacket
92 = ADDR()
3F = eol (end-of-instruction, newline)

SEEK #filePath,numVars*SIZE(vars)+2
2B 54 80 0252 4B 81 0259 95 F2 0027 94 EC 8D 02 E7 3F
SEEK # filePath , numVars <size> vars SIZE() * <bc> 2 + <eol>

2B = SEEK
54 = #
80 0252 = filePath
4B = , (comma)
81 0259 = numVars
95 = <size>
F2 0027 = vars
94 = SIZE()
EC = * (mult)
8D 02 = <bc> 2 (byte constant)
E7 = + (add)
3F = <eol> (end-of-instruction, newline)

92 ADDR() 93 <addr>
94 SIZE() 95 <size>
BE EOF() B4 PEEK()

String Function Tokens

9C SUBSTR()
BF TRIM$()
C0 MID$()
C1 LEFT$()
C2 RIGHT$()

String-to-Number Function Tokens

B6 VAL()
B7 LEN()
B8 ASC()

Number-to-String Function Tokens

C3 CHR$()
C4 STR$() (BYTE/INTEGER)
C5 STR$() (REAL)
C6 DATE$

Logical Operator Tokens

B5 LNOT()
B9 LAND()
BA LOR()
BB LXOR()

Boolean Function Tokens

CD NOT()
CE - (BYTE/INTEGER)
CF - (REAL)
D0 AND
D1 OR
D2 XOR

Comparison Operator Tokens

BYTE/
INTEGER REAL STRING BOOLEAN
D3 > D4 > D5 >
D6 < D7 < D8 <
D9 <> DA <> DB <> DC <>
DD = DE = DF = E0 =
E1 >= E2 >= E3 >=
E4 <= E5 <= E6 <=

Math Operator Tokens

BYTE/
INTEGER REAL STRING
E7 + E8 + E9 +
EA - EB -
EC * ED *
EE / EF /
F0 ^ F1 **

I-Code Token List

Token Name Used In Description
00 GLOBAL Reserved Global Variable
01 PARAM Editor
01 READ I-Code File Mode
02 TYPE Editor
02 WRITE I-Code File Mode
03 DIM Editor
03 UPDATE I-Code File Mode
04 DATA I-Code/Editor
04 EXEC I-Code File Mode
05 STOP I-Code/Editor
05 READ+EXEC I-Code File Mode
06 BYE I-Code/Editor
06 WRITE+EXEC I-Code File Mode
07 TRON I-Code/Editor
07 UPDATE+EXEC I-Code File Mode
08 TROFF I-Code/Editor
09 PAUSE I-Code/Editor
0A DEG I-Code/Editor
0B RAD I-Code/Editor
0C RETURN I-Code/Editor
0D LET I-Code/Editor
0E <cva> I-Code/Editor Complex Variable Assignment
0F POKE I-Code/Editor
10 IF I-Code/Editor
11 ELSE I-Code/Editor
12 ENDIF I-Code/Editor
13 FOR I-Code/Editor
14 NEXT I-Code/Editor
15 WHILE I-Code/Editor
16 ENDWHILE I-Code/Editor
17 REPEAT I-Code/Editor
18 UNTIL I-Code/Editor
19 LOOP I-Code/Editor
1A ENDLOOP I-Code/Editor
1B EXITIF I-Code/Editor
1C ENDEXIT I-Code/Editor
1D ON I-Code/Editor
1E ERROR I-Code/Editor
1F GOTO Editor Unbound
20 GOTO I-Code/Editor Bound
21 GOSUB Editor Unbound
22 GOSUB I-Code/Editor Bound
23 RUN I-Code/Editor
24 KILL I-Code/Editor
25 INPUT I-Code/Editor
26 PRINT I-Code/Editor ? Becomes PRINT in the Editor
27 CHD I-Code/Editor
28 CHX I-Code/Editor
29 CREATE I-Code/Editor
2A OPEN I-Code/Editor
2B SEEK I-Code/Editor
2C READ I-Code/Editor
2D WRITE I-Code/Editor
2E GET I-Code/Editor
2F PUT I-Code/Editor
30 CLOSE I-Code/Editor
31 RESTORE I-Code/Editor
32 DELETE I-Code/Editor
33 CHAIN I-Code/Editor
34 SHELL I-Code/Editor
35 BASE0 I-Code/Editor
36 BASE1 I-Code/Editor
37 REM Editor ! Becomes REM in the Editor
38 (* Editor
39 END I-Code/Editor
3A <ulref> Editor Unbound Line Reference
3B <blref> I-Code/Editor Bound Line Reference
3C <dex> I-Code/Editor Direct Execution (Unimplemented)
3D PROCEDURE Editor Procedure start
3D <erl> Editor/Debug Error Line
3E \ I-Code/Editor End-of-Instruction, Continue Line
3F <eol> I-Code/Editor End-of-Instruction and Line
40 BYTE Editor
40 fbyte I-Code/Editor VDT Entry, Field Byte Variable
41 INTEGER Editor
41 finteger I-Code/Editor VDT Entry, Field Integer Variable
42 REAL Editor
42 freal I-Code/Editor VDT Entry, Field Real Variable
43 BOOLEAN Editor
43 fboolean I-Code/Editor VDT Entry, Field Boolean Variable
44 STRING Editor
44 fstring I-Code/Editor VDT Entry, Field String Variable
45 THEN I-Code/Editor
45 frecord I-Code/Editor VDT Entry, Field Record Variable
46 TO I-Code/Editor
47 STEP I-Code/Editor
48 DO I-Code/Editor
48 fvectorb I-Code/Editor VDT Entry, Field 1 Dimensional Byte Array
49 USING I-Code/Editor
49 fvectori I-Code/Editor VDT Entry, Field 1 Dimensional Integer Array
4A : I-Code/Editor File Mode Operator
4A fvectorr I-Code/Editor VDT Entry, Field 1 Dimensional Real Array
4B , I-Code/Editor Comma Separator
4B fvectorl I-Code/Editor VDT Entry, Field 1 Dimensional Boolean Array
4C : I-Code/Editor Colon
4C fvectors I-Code/Editor VDT Entry, Field 1 Dimensional String Array
4D ( I-Code/Editor Left Parenthesis
4D fvectoru I-Code/Editor VDT Entry, Field 1 Dimensional Record Array
4E ) I-Code/Editor Right Parenthesis
4F [ I-Code/Editor Left Bracket
50 ] I-Code/Editor Right Bracket
50 ftableb I-Code/Editor VDT Entry, Field 2 Dimensional Byte Array
51 ; I-Code/Editor Semi-colon
51 ftablei I-Code/Editor VDT Entry, Field 2 Dimensional Integer Array
52 := I-Code/Editor AssignmentOperator
52 ftabler I-Code/Editor VDT Entry, Field 2 Dimensional Real Array
53 = I-Code/Editor AssignmentOperator
53 ftablel I-Code/Editor VDT Entry, Field 2 Dimensional Boolean Array
54 # I-Code/Editor Channel (Path) Number Operator
54 ftables I-Code/Editor VDT Entry, Field 2 Dimensional String Array
55 <ivgt> I-Code/Editor Invisible GOTO (used in many statements)
55 <ivgt> I-Code/Editor Invisible GOTO (special case in ON var GOTO/GOSUB statements)
55 ftableu I-Code/Editor VDT Entry, Field 2 Dimensional Record Array
56 Unused
57 Unused
58 fmatrixb I-Code/Editor VDT Entry, Field 3 Dimensional Byte Array
59 fmatrixi I-Code/Editor VDT Entry, Field 3 Dimensional Integer Array
5A fmatrixr I-Code/Editor VDT Entry, Field 3 Dimensional Real Array
5B fmatrixl I-Code/Editor VDT Entry, Field 3 Dimensional Boolean Array
5C fmatrixs I-Code/Editor VDT Entry, Field 3 Dimensional String Array
5D fmatrixu I-Code/Editor VDT Entry, Field 3 Dimensional Record Array
5E Unused
5F Unused
60 byte I-Code/Editor VDT Entry, Byte Variable
61 integer I-Code/Editor VDT Entry, Integer Variable
62 real I-Code/Editor VDT Entry, Real Variable
63 boolean I-Code/Editor VDT Entry, Boolean Variable
64 string I-Code/Editor VDT Entry,StringVariable
65 record I-Code/Editor VDT Entry, Record Variable
66 Unused
67 Unused
68 vectorb I-Code/Editor VDT Entry, 1 Dimensional Byte Array
69 vectori I-Code/Editor VDT Entry, 1 Dimensional Integer Array
6A vectorr I-Code/Editor VDT Entry, 1 Dimensional Real Array
6B vectorl I-Code/Editor VDT Entry, 1 Dimensional Boolean Array
6C vectors I-Code/Editor VDT Entry, 1 Dimensional String Array
6D vectoru I-Code/Editor VDT Entry, 1 Dimensional Record Array
6E Unused
6F Unused
70 tableb I-Code/Editor VDT Entry, 2 Dimensional Byte Array
71 tablei I-Code/Editor VDT Entry, 2 Dimensional Integer Array
72 tabler I-Code/Editor VDT Entry, 2 Dimensional Real Array
73 tablel I-Code/Editor VDT Entry, 2 Dimensional Boolean Array
74 tables I-Code/Editor VDT Entry, 2 Dimensional String Array
75 tableu I-Code/Editor VDT Entry, 2 Dimensional Record Array
76 Unused
77 Unused
78 matrixb I-Code/Editor VDT Entry, 3 Dimensional Byte Array
79 matrixi I-Code/Editor VDT Entry, 3 Dimensional Integer Array
7A matrixr I-Code/Editor VDT Entry, 3 Dimensional Real Array
7B matrixl I-Code/Editor VDT Entry, 3 Dimensional Boolean Array
7C matrixs I-Code/Editor VDT Entry, 3 Dimensional String Array
7D matrixu I-Code/Editor VDT Entry, 3 Dimensional Record Array
7E Unused
7F Unused
80 byte I-Code/Editor Instruction, Simple Byte Variable
80 pbyte I-Code/Editor VDT Entry, Parameter Byte Variable
80 DIR I-Code File Mode
81 integer I-Code/Editor Instruction, Simple Integer Variable
81 pinteger I-Code/Editor VDT Entry, Parameter Integer Variable
81 READ+DIR I-Code File Mode
82 real I-Code/Editor Instruction, Simple Real Variable
82 preal I-Code/Editor VDT Entry, Parameter Real Variable
82 WRITE+DIR I-Code File Mode
83 boolean I-Code/Editor Instruction, Simple Boolean Variable
83 pboolean I-Code/Editor VDT Entry, Parameter Boolean Variable
83 UPDATE+DIR I-Code File Mode
84 string I-Code/Editor Instruction, Simple String Variable
84 pstring I-Code/Editor VDT Entry, Parameter String Variable
84 EXEC+DIR I-Code File Mode
85 record/p I-Code/Editor Instruction,Record, Parameter (Simple/Record) Variable
85 vector/p I-Code/Editor Instruction, 1 Dimensional Array, Parameter 1 Dimensional Array Variable
85 table/p I-Code/Editor Instruction, 2 Dimensional Array, Parameter 2 Dimensional Array Variable
85 matrix/p I-Code/Editor Instruction, 3 Dimensional Array, Parameter 3 Dimensional Array Variable
85 precord I-Code/Editor VDT Entry, Parameter Record Variable
85 READ+EXEC+DIR I-Code File Mode
86 vector/p I-Code/Editor Instruction, 1 Dimensional Array
86 WRITE+EXEC+DIR I-Code File Mode
87 table/p I-Code/Editor Instruction, 2 Dimensional Array
87 UPDATE+EXEC+DIR I-Code File Mode
88 matrix/p I-Code/Editor Instruction, 3 Dimensional Array
88 pvectorb I-Code/Editor VDT Entry, Parameter 1 Dimensional Byte Array
89 varm I-Code/Editor Instruction, Simple/Record Variable Mirror
89 pvectori I-Code/Editor VDT Entry, Parameter 1 Dimensional Integer Array
8A fvectorm I-Code/Editor VDT Entry, Field 1 Dimensional Array Mirror
8A pvectorr I-Code/Editor VDT Entry, Parameter 1 Dimensional Real Array
8B ftablem I-Code/Editor VDT Entry, Field 2 Dimensional Array Mirror
8B pvectorl I-Code/Editor VDT Entry, Parameter 1 Dimensional Boolean Array
8C fmatrixm I-Code/Editor VDT Entry, Field 3 Dimensional Array Mirror
8C pvectors I-Code/Editor VDT Entry, Parameter 1 Dimensional String Array
8D <bc> I-Code/Editor BYTE Constant (Literal)
8D pvectoru I-Code/Editor VDT Entry, Parameter 1 Dimensional Record Array
8E <ic> I-Code/Editor INTEGER Constant (Literal)
8F <rc> I-Code/Editor REAL Constant (Literal)
90 " I-Code/Editor STRING Constant (Literal) - Beginning
90 ptableb I-Code/Editor VDT Entry, Parameter 2 Dimensional Byte Array
91 $ I-Code/Editor Hexadecimal Constant (Literal)
91 ptablei I-Code/Editor VDT Entry, Parameter 2 Dimensional Integer Array
92 ADDR() I-Code/Editor
92 ptabler I-Code/Editor VDT Entry, Parameter 2 Dimensional Real Array
93 <addr> I-Code/Editor Second Byte of ADDR()
93 ptablel I-Code/Editor VDT Entry, Parameter 2 Dimensional Boolean Array
94 SIZE() I-Code/Editor
94 ptables I-Code/Editor VDT Entry, Parameter 2 Dimensional String Array
95 <size> I-Code/Editor Second Byte of SIZE()
95 ptableu I-Code/Editor VDT Entry, Parameter 2 Dimensional Record Array
96 POS() I-Code/Editor
97 ERR() I-Code/Editor
98 MOD() I-Code/Editor Byte/Integer
98 pmatrixb I-Code/Editor VDT Entry, Parameter 3 Dimensional Byte Array
99 MOD() I-Code/Editor Real
99 pmatrixi I-Code/Editor VDT Entry, Parameter 3 Dimensional Integer Array
9A RND() I-Code/Editor
9A pmatrixr I-Code/Editor VDT Entry, Parameter 3 Dimensional Real Array
9B PI I-Code/Editor
9B pmatrixl I-Code/Editor VDT Entry, Parameter 3 Dimensional Boolean Array
9C SUBSTR() I-Code/Editor
9C pmatrixs I-Code/Editor VDT Entry, Parameter 3 Dimensional String Array
9D SGN() I-Code/Editor
9D pmatrixu I-Code/Editor VDT Entry, Parameter 3 Dimensional Record Array
9E SGN() I-Code/Editor
9F SIN() I-Code/Editor
A0 COS() I-Code/Editor
A0 <subr> I-Code/Editor Named Subroutine
A1 TAN() I-Code/Editor
A2 ASN() I-Code/Editor
A3 ACS() I-Code/Editor
A4 ATN() I-Code/Editor
A5 EXP() I-Code/Editor
A6 ABS() I-Code/Editor
A7 ABS() I-Code/Editor
A8 LOG() I-Code/Editor
A9 LOG10() I-Code/Editor
AA SQRT() I-Code/Editor
AB SQR() I-Code/Editor Becomes SQRT() in the Code
AC INT() I-Code/Editor Byte/Integer
AD INT() I-Code/Editor Real
AE FIX() I-Code/Editor Byte/Integer
AF FIX() I-Code/Editor Real
B0 FLOAT() I-Code/Editor Byte/Integer
B1 FLOAT() I-Code/Editor Real
B2 SQ() I-Code/Editor Byte/Integer
B3 SQ() I-Code/Editor Real
B4 PEEK() I-Code/Editor
B5 LNOT() I-Code/Editor LogicalNOT
B6 VAL() I-Code/Editor
B7 LEN() I-Code/Editor
B8 ASC() I-Code/Editor
B9 LAND() I-Code/Editor Logical AND
BA LOR() I-Code/Editor Logical OR
BB LXOR() I-Code/Editor Logical XOR
BC TRUE I-Code/Editor
BD FALSE I-Code/Editor
BE EOF() I-Code/Editor
BF TRIM$() I-Code/Editor
C0 MID$() I-Code/Editor
C1 LEFT$() I-Code/Editor
C2 RIGHT$() I-Code/Editor
C3 CHR$() I-Code/Editor
C4 STR$() I-Code/Editor Byte/Integer
C5 STR$() I-Code/Editor Real
C6 DATE$ I-Code/Editor
C7 TAB I-Code/Editor
C8 <ritc> I-Code/Editor Real->Byte/Integer Type Conversion
C8 <fix1> I-Code/Editor Fix Top of Stack
C9 <fix2> I-Code/Editor Fix Second on Stack
CA <fix3> I-Code/Editor Fix Third on Stack
CB <irtc> I-Code/Editor Byte/Integer->Real Type Conversion
CB <flt1> I-Code/Editor Float Top of Stack
CC <flt2> I-Code/Editor Float Second on Stack
CD NOT() I-Code/Editor
CE - I-Code/Editor (Monadic) Negate Byte/Integer
CF - I-Code/Editor (Monadic) Negate Real
D0 AND I-Code/Editor
D1 OR I-Code/Editor
D2 XOR I-Code/Editor
D3 > I-Code/Editor Byte/Integer Comparison Operator
D4 > I-Code/Editor Real Comparison Operator
D5 > I-Code/Editor String Comparison Operator
D6 < I-Code/Editor Byte/Integer Comparison Operator
D7 < I-Code/Editor Real Comparison Operator
D8 < I-Code/Editor String Comparison Operator
D9 <> I-Code/Editor Byte/Integer Comparison Operator >< is converted to <> in the code
DA <> I-Code/Editor Real Comparison Operator >< is converted to <> in the code
DB <> I-Code/Editor String Comparison Operator >< is converted to <> in the code
DC <> I-Code/Editor Boolean Comparison Operator >< is converted to <> in the code
DD = I-Code/Editor Byte/Integer Comparison Operator
DE = I-Code/Editor Real Comparison Operator
DF = I-Code/Editor String Comparison Operator
E0 = I-Code/Editor Boolean Comparison Operator
E1 >= I-Code/Editor Byte/Integer Greater/Equal Operator
E2 >= I-Code/Editor Real Greater/Equal Operator
E3 >= I-Code/Editor String Greater/Equal Operator
E4 <= I-Code/Editor Byte/Integer Less/Equal Operator
E5 <= I-Code/Editor Real Less/Equal Operator
E6 <= I-Code/Editor String Less/Equal Operator
E7 + I-Code/Editor Byte/Integer Add Operator
E8 + I-Code/Editor Real Add Operator
E9 + I-Code/Editor String Concantenate Operator
EA - I-Code/Editor Byte/Integer Subtract Operator (Dyadic)
EB - I-Code/Editor Real Subtract Operator (Dyadic)
EC * I-Code/Editor Byte/Integer Multiply Operator
ED * I-Code/Editor Real Multiply Operator
EE / I-Code/Editor Byte/Integer Divide Operator
EF / I-Code/Editor Real Divide Operator
F0 ^ I-Code/Editor Exponent Operator
F1 ** I-Code/Editor Exponent Operator
F2 varm/p I-Code/Editor Instruction, Simple/Record, Parameter Variable Mirror
F3 vectorm/p I-Code/Editor Instruction, 1 Dimensional Array, Parameter 1 Dimensional Array Mirror
F4 tablem/p I-Code/Editor Instruction, 2 Dimensional Array, Parameter 2 Dimensional Array Mirror
F5 matrixm/p I-Code/Editor Instruction, 3 Dimensional Array, Parameter 3 Dimensional Array Mirror
F6 field I-Code/Editor Instruction, Field Variable
F7 UPDATE Editor File Mode
F7 fvector I-Code/Editor Instruction, Field 1 Dimensional Array
F8 EXEC Editor File Mode
F8 ftable I-Code/Editor Instruction, Field 2 Dimensional Array
F9 DIR Editor File Mode
F9 fmatrix I-Code/Editor Instruction, Field 3 Dimensional Array
FA Unused
FB Unused
FC Unused
FD Unused
FE Unused
FF " I-Code/Editor STRING Constant (Literal) - Terminator