Doc version 5.5.0.2
Last revised 04/28/2004

For AiroPeek/AiroPeek NX v2.0 or higher, EtherPeek v5.1 or higher, EtherPeek NX v2.1 or higher, GigaPeek NX v1.0 or higher, Omnipeek v1.0 or higher, WANPeek NX v1.0 or higher

Table of Contents

Introduction
Overview
Instructions
Global Variables
Local Variables
The Previous Test
String Arrays
File Formats
Threaded Decoding
Super Globals
Examples
Creating Your Own Decoders
New 802.2 LSAP Types
New SNAP Types
New IP Types
New TCP Types
New UDP Types
Decoder Instructions
Data Formats
Data Format Representation
Data Location Field
Data Style Field
Label Format Representation
Label Newline Field
Label Location Field
Label Style Field
Instruction Index

Introduction

This document is a guide to Savvius' language for decoding packets in the Peek products. The language described here enables our customers to extend the decoders we have provided or to create new ones. We have devised a simple, interpreted language designed specifically for displaying network frames for several media types. The language includes instructions for displaying data, controlling the sequence of instructions, manipulating data values, and conditional execution. The format of decoder files, a detailed description of each instruction and its effects, and the tools needed for creating decoder files are discussed.

Overview

The decode of a protocol is accomplished through a collection of decoders. Each decoder is uniquely named and contains a sequence of decode instructions. An important part of the decoding process is the ability of decoders to link to other decoders. This allows a modular design, and eliminates the need for duplication of decoders for the decoding of different packets with the same first layers. Decoders of one file may use decoders of others.

The decoding process follows the layers of the protocols from the bottom layer to the top, and as layers are encountered, decoders will call other decoders and relinquish the decoding task to them. There is some strong presumption that the bottom layers appear first in the packet although there is some ability to handle the decoding when this is not exactly the case.

Each decoder is a combination of one or more decoding instructions. Most instructions are composed of a decode instruction, a value, some option fields, and a string. When the user decides to decode a packet, the decode manager is called with a pointer to the first byte of the packet. As decode instructions are encountered and executed, this pointer is incremented as dictated by the instruction type, in preparation for the next instruction. Packet data that is processed by the instruction may be saved for later use in global or local variables.

Stated another way, the pointer to the data in the packet and a decoder instruction operate on one or more bytes in the packet and the pointer moves along correspondingly. In some cases, an instruction may operate only on bits within a byte.

When the decode manager runs out of instructions, it will display the rest of the packet in a generic data format. Depending on the media type, the last of the remaining bytes are reserved for the FCS (4 bytes, Ethernet or Wireless), or not (0 bytes, Token Ring). If the decode manager runs out of packet data before exhausting the instructions an error message is displayed, notifying the user that not enough bytes were available. Nevertheless, using the different patterns of instructions, it is still possible in some cases to scan beyond the end of the packet or to create infinite loops so some caution should be exercised.

Instructions

A decoder is a sequence of one or more instructions. A typical instruction has a type, a value, an option, a data style, a label style, and a string (that may be empty).

Type A four character code identifying the decoder instruction.
Value A signed 32-bit value. The two high bits are used to provide options for certain instructions.
Global A signed 32-bit value.  The 26 high bits are used to provide options for certain instructions.  The low 5 bits represent the index of a global variable.
Data Style A 1-byte value containing fields for text location and style.
Label Style A 1-byte value containing fields for text location, style, and a new line option.
String An ASCII string to be used as a label or the name of another decoder or a string array.

Fundamentally, a single decoder instruction is intended to provide enough information to yield a label and a value after that label. The decode instruction also includes formatting information about both the label and data parts. Of course, there is no requirement to do both a label and data portion in each instruction and there are some decoder instructions that just operate on the data without displaying either a label or data, or instructions which just control the flow of instructions: test and branch, subroutine call, etc.

Global Variables

The decoders have access to 32 long word (32-bit) global areas, where they may save information for later use. There is also one implicit Boolean global, for use in test instructions. These globals provide the ability to interpret data in later parts of a packet, in accordance to values in earlier bytes of that packet.

Global Variable Format Representation

Bit(s) Meaning
0x00000040 Local bit on global
0x00000080 Register bit on value;
0x00000100 Previous Test bit (TEQU family only)
0x00080000 Constant value bit
0x0FF00000 Number of bits to skip
0x20000000 Skip bit
0x40000000 Branch bit
0x80000000 Debugger break

Local Variables

The decoders have access to 32 long word (32-bit) local variables, where they may save information for later use inside a particular decode. These local variables provide the ability to use data from earlier parts of a decode. To use a local, instead of setting the Most Significant Bit(MSB), you will instead set the 2nd MSB. See example below, which adds 3 to the local variable 2. **Note: You can only move global variables to local variables.

ADDG 3 42;		* add 3 to local 2
ADDG 3 82;		* add global 3 to local 2
ADDG 40000003 c2;		* add local 3 to local 2
As indicated by any given instruction, the global field will determine which local to use in the operation. For example, after reading two bytes of the packet, you may wish to store it in local number 3, for use later, like the example above.

The Previous Test

Several decoder instructions perform tests to be used in other conditional instructions. For example, one instruction may compare packet data to a value or a value to a global and then a subsequent instruction will conditionally display a string or branch to another decoder. The decoder mechanism keeps track of the status of tests. See the table of instruction descriptions for instructions that take advantage of this feature.  Here is an example:

void Test;
  MOVE 2 1;		* move 2 into g2
  SEQU 2 1;		* is 2 == g1 ?
  SKIP 1;
    LABL -They are not equal;
  TRTS;

Below is a variation of the example using ENDS instead of specifying the actual number to skip:

void Test;
  MOVE 2 1; 		* move 2 into g2
  SEQU 2 1; 		* is 2 == g1 ?
   SKIP;
    LABL -They are not equal;
   ENDS;
   TRTS;

And the "coup de grat" is the following example that sets the "skip bit" on the SEQU that instructs it to skip the instructions up to the ENDS instruction.  In other words, if the test is true the enclosed block is executed.   

void Test;
  MOVE 2 1;		* move 2 into g2
  SEQU 2 20000001;		* if 2 == g2 ?
    LABL -They are equal;
  ENDS;
  TRTS;

In the above example the skip bit is the 3rd highest significant bit on the global.   The skip bit is supported by all of the S* functions including SEQU, SNEQ, SLTE, SGTE, and SBIT.

String Arrays

The other major component of decoders are string arrays referred to here as "str#" resources (because they're identified by the string "str#"). String arrays are identified by a unique name and are composed of a list of strings located with a 1-based index. Indexed string arrays provide their own index.  Decoders can make use of string arrays by extracting data from a packet, possibly doing some arithmetic, and either displaying a string from an array or calling a function specified in an array.

String arrays are identified by the lowercase string "str#" followed by a unique name. Each string in the array appears on a line by itself terminated by a semicolon. Here is an example:

str# MyStrings;
  String1;
  String2;
  String3;
  ;
  String5;
  String6;

The above string array is accessed in a linear manner.   The line with only a semi-colon specifies an empty string entry.  A variation of the string array is the indexed string array.  This type of str# allows the index of entries to be specified with a hex value of the entry followed by a '|' followed by a string.   Here is an example:

str# MyStrings2;
  1 | String1;
  5 | String5;
  8 | String8; 
  9 | String9;

Another variation of the string is the mixed string array which includes indexed and non-indexed entries.  Here is an example:

str# MyBitStr;
  3 | 1... Bit 3 is set;
      0... Bit 3 is not set;
  2 | .1.. Bit 2 is set;
      .0.. Bit 2 is not set; 
  1 | ..1. Bit 1 is set;
      ..0. Bit 1 is not set;

The string array in the example above is used with the BST# instruction.

File Formats

Decoders are stored in text files located in a directory adjacent to the program. Under MacOS, this directory is called "Packet Decoders"; under Windows, simply "Decodes". Individual decoders are identified by the lowercase string "void" followed by a unique name. Individual instructions follow the format: [instruction][value] [global] [data format] [label format] [string], where each element is separated by a tab character or one or more spaces. Each line is terminated by a semicolon. Here is an example:

void FTP;
  TEQU 0 10 0 30 FTP No Cmd Data;
  TLTE 5dc 10 0 30 FTP No Cmd Data;
  LABL 0 0 0 b1 FTP Control - File Transfer Protocol;
  TNXT 0 0 0 0 FTP Cmd or Reply; **

The same function could also be written as:

void FTP()
  {
     TEQU( 0, g[0x10], 0, 0x30, "FTP No Cmd Data");
     TLTE( 0x5dc, g[0x10], 0, 0x30, "FTP No Cmd Data");
     LABL( 0, 0, 0, 0xb1, "FTP Control - File Transfer Protocol");
     TNXT( 0, 0, 0, 0, "FTP Cmd or Reply");
  }

In the above example the parameters are enclosed in parenthesis.  When parenthesis are used numbers are assumed to be decimals.  In order to specify hex prefix numbers with 0x.  In order to specify globals and locals use the g[] and l[] arrays.

Lines beginning with an asterisk "*" are ignored and can be used for comments.

**Notes: A dash can be used in place of the four number parameters when they are all equal to zero, i.e.,

TNXT -FTP Cmd or Reply;

can replace:

TNXT 0 0 0 0 FTP Cmd or Reply;

The TSUB instruction has become implicit for subroutine calls. It is not necessary to prefix a subroutine call with TSUB anymore. For example, what used to be:

TSUB 0 0 0 0 Foo;

or:

TSUB -Foo;

can also be simply:

Foo;

Specifying TSUB will still work but is not necessary.

Assignments and math on locals and globals can be done using the following syntax:

g[1] = 1;
l[1] = 2;
g[4] = l[4];
l[3] = g[6];

g[1] += 1;
l[1] += 2;
g[4] += l[4];
g[7] += g[6];
l[3] += g[6];
l[3] += l[6];

g[1] *= 0;
l[2] /= 2;
g[3] %= 1;
g[4] &= l[4];
g[5] |= 5;

Tests on locals and globals can be done using the following syntax:

if g[2] == 1 {
  LABL 0 0 90 c2 "g[2] == 0";
}

if g[2] == l[2] {
  LABL 0 0 90 c2 "g[2] == l[2]";
}

if l[1] == g[1] {
  LABL 0 0 90 c2 "l[1] == g[1]";
}

Tests can also be nested:

if g[1] <= l[2] {
  LABL 0 0 90 c2 "g[1] <= l[2]";

  if g[2] <= l[1] {
    LABL 0 0 90 c2 "g[2] <= l[1]";
  }
}

Packet data can be accessed in the following ways:

g[1] = pb[1];		* means GBYT 1 1;
g[1] = pb[0];		* means GBYT 0 1;
g[1] = pw[0];		* means GWRD 0 1;
g[1] = pl[0];		* means GLNG 0 1;
l[1] = pl[0];		* means GLNG 0 41;

In the above examples 'p' stands for packet, 'b' for byte, 'w' for word, and 'l' for long

While Loops

The following is example of while loops:

void main()
{
  g[1] = 0;
  while (g[1] < 5)
  {
    g[1] += 1;
    DGLB( 0, g[1], 0x90, 0xc2, "g[1]:");
  }

  g[1] = 5;
  while (g[1] > 0)
  {
    g[1] -= 1;
    DGLB( 0, g[1], 0x90, 0xc2, "g[1]:");
  }
}

Threaded Decoding

Packets usually contain the information needed to decode them into their protocol components. However, some protocol stacks use transactions in the form of a request packet followed by a response packet and the response packet does not contain any information about the type of request to which is responding. For example, in AFP (the AppleTalk File Protocol), a request will be made to get information about a file, and the response will contain the requested information, but the response packet does not identify itself as being the answer to a file information request. Because of the lack of information in the response packet, it could just as easily be interpreted as a response to a get volume parameters request. As a solution to this problem, the decoder language contains the WHOA instruction. This instruction takes the name of an indexed string as its string parameter. Each name in the string array is a choice of how to decode the next portion of the packet and this name is also the name of the decoder to be used. These choices are presented to the user in a dialog and the value field contains a number that is the index of the default choice that is highlighted in the list.

With this as the basis, it should be clear that the user must manually select a decode choice for those protocols that do not identify their responses. As an implementation detail, the program tends to remember the last choice selected and uses that one again for subsequent packets. However, such inference is often incorrect.

To extend the capabilities of the decoders, an additional mechanism was added that is referred to here as threaded decoding. First, the MARK instruction is added so that when a request packet is encountered, the packet is "marked" with the relevant information; in particular, the type of response that will be subsequently expected. Then, when the WHOA instruction is encountered at some later packet, the WHOA instruction checks to see if there is a marked packet that tells it how to decode the current packet. If so, the user is NOT prompted for input, but instead it is assumed that the decoding should be done as the previous MARK instruction indicated.

To clarify and illustrate the mechanism, consider the following example. A certain protocol sets up a socket-to-socket connection. Requests are made and non-request identifying responses are given. In the implementation of the protocol, the response is directed to the requester to a socket number that is unique on the requester's node. To write a decoder program for this situation, during the decode of the request the MARK instruction is processed. The string field of the MARK instruction contains the name of a string array that contains the names of all the possible response types. The value field tells which option is the correct one for this request. The source socket number is contained in a global variable and this global is passed to the MARK instruction. In processing the MARK instruction, the name of the string array (the str#), the choice of which item to use in the array, the number of the packet and the socket number passed in the global variable are stored together in LIFO memory, a.k.a., a cache.

In writing a decode program for the response, at the appropriate point where different types for the response are possible, the WHOA instruction is called. The string field of the WHOA instruction contains the name of a string array that contains the names of the all the possible response types. The value field tells which of these options is the default. The destination socket of the response has been saved in a global variable. In processing the WHOA instruction, the cache is searched for a match of both the socket number value contained in the global and the string array name. If a match is found, the choice from the possibilities, as stored in the cache by the MARK instruction, is used to decode the next portion of the packet. Moreover, if the WHOA instruction contains the number of a global variable in the high 8 bits of the value field, that global will get the number of the packet that contained the request placed into its value. If there is a match in the cache, execution continues with the designated decoder. If there is no match and the user makes a choice from those presented, execution continues with the corresponding chosen decoder. In all other cases, including when cancel is chosen, execution continues with the instruction following the WHOA instruction. Please see example below:

Mark and Whoa code example
1) Open decodes.dcd
2) Search for void SNMP

void SNMP;
     ASN1_Init;
     MOVE 0 11;  *enum testing is off
     LABL  0  0  0 b1 SNMP - Simple Network Management Protocol;
     WHOA  0  1  0  0 SNMP Exp Opt;
     WHOA  0  2  0  0 SNMP Exp Opt;
     SEQU a1  1;
     SKIP  5  0;
     SEQU a2  1;
     SKIP  3  0;
     MARK  2  2  0  0 SNMP Exp Opt;
     WHOA  0  2  0  0 SNMP Exp Opt;
     TNXT -Summary SNMP Fields;
     MARK  2  1  0  0 SNMP Exp Opt;
     WHOA  0  1  0  0 SNMP Exp Opt;
     TNXT -Summary SNMP Fields;
3) Notice MARK on line 11. It translates to MARK this packet as a possible help for a following packet, use the string array SNMP Exp Out to figure out the next possible decode. The value field tells which string to use based on the value global field, which is 2; later if this value in the global is matched, then it will use the decode specified in the string array at position 2. It then stores this in a LIFO(Last In First Out) cache.
4) Notice WHOA on line 12. It translates to decode this packet based on information from a previous packet. Check global location 2 and see what value is there. If the value indexes to a string in the given string array, SNMP Exp Out, then jump to that named decoder.

Another MARK and WHOA code example
1) Open decodes.dcd
2) Search for void TCP::Ports

void TCP::Ports()
{
	MOVE  0   9;
	WHOA  0   2 0 0 Alternate Decoders;
	WHOA  0   2 0 0 H323_Decoders;
	WHOA  0   2 0 0 MegacoText::Str;
	WHOA  0   2 0 0 SIP::MW_List;
	MOVE  1   9;
	
	TSB#  0   2 -TCP::Ports_Str;
	
	SKIP 1;
	MOVE    2 9;     // g[9]==2 means we did not find a match
}
3) Notice the third WHOA. It refers to MegacoText::Str. If you search for str# MegacoText::Str, you'll find that there is only one entry for this list. This is because in the beginning of the Megaco request, it marks the port as the valid Megaco port. This is done because Megaco can switch ports depending on which thread you are viewing. So, when there is a MARK, global 2 contains the port number that Megaco currently runs on. In that case, when there is a WHOA, it can check against that MARK to see if Megaco is a valid entry. If it is a valid entry, it will use the MARK's value field to determine which decoder function to branch off to [in this case, MegacoText is specified].

One last example of MARK and WHOA seen in the Novell decodes.
1) Open decodes.dcd
2) Search for void NCP Reply.

void NCP Request;
	GWRD 0 b;
	DBYT 0 14 90 c2 Sequence number:;
	...

void NCP Reply;
	GWRD 0 b;
	DBYT 0 14 90 c2 Sequence number:;
	...
	WHOA 0 14 0 0 NCP::Type_17::MW_List;
	WHOA 0 14 0 0 NCP::Type_21::MW_List;
	WHOA 0 14 0 0 NCP::Type_22::MW_List;
	WHOA 0 14 0 0 NCP::Type_23::MW_List;
	WHOA 0 14 0 0 NCP::Type_32::MW_List;
	WHOA 0 14 0 0 NCP::Type_34::MW_List;
	WHOA 0 14 0 0 NCP::Type_35::MW_List;
	WHOA 0 14 0 0 NCP::Type_36::MW_List;
	WHOA 0 14 0 0 NCP::Type_86::MW_List;
	WHOA 0 14 0 0 NCP::Type_87::MW_List;
	WHOA 0 14 0 0 NCP::Type_90::MW_List;
	WHOA 0 14 0 0 NCP::Type_104::MW_List;
	WHOA 0 14 0 0 NCP::Type_111::MW_List;
	WHOA 0 14 0 0 NCP::Type_114::MW_List;
	WHOA 0 14 0 0 NCP::Type_123::MW_List;
	WHOA 0 14 0 0 NCP::Type_131::MW_List;
	WHOA 0 14 0 0 NCP::Type_Loners::MW_List;
	WHOA 0 b 0 c2 Adv NW Rep Opt;
	TNXT -NW Reply Any Left;
3) The beginning few lines were taken out, but notice a long list of WHOA's. Novell Core Protocol works by having the request specify what the response will be and it also can contain information that the response will need in order to decode the packet properly.
a) Notice also in the second line of both void NCP Request and void NCP Reply, the line "DBYT 0 14 90 c2 Sequence Number." That is the value that is used in the MARK and the WHOA. So dependent on the sequence number, the MARK and WHOA will check the value in global 14 to confirm if it is valid or not.
b) The next step is to MARK all of the request packets that can have a response. Search for void NCP::Type_22::52. At the beginning of the function, you'll find:
void NCP::Type_22::52;
	MARK 34 14 0 0 NCP::Type_22::MW_List;
	...

str# NCP::Type_22::MW_List;
	 1 | NCP::Type_22::01R;
	 2 | NCP::Type_22::02R;
	 5 | NCP::Type_22::05R;
	 6 | NCP::Type_22::06R;
	12 | NCP::Type_22::12R;
	...
	51 | NCP::Type_22::51R;
	52 | NCP::Type_22::52R;
It MARKS to use the 52th number [0x34 == 52 decimal] specified in the list.
c) To summarize, MARK will save global 14 [sequence number] to be checked on the WHOA as well as the value field [0x34] to be used as an index to the list of responses. When the WHOA is called, if global 14 matches, then it will use the MARKed value field to branch to the correct decoder.

Super Globals

Another way to use threaded decoding is to use super globals. These are used to carry information from one packet to the next. For example, let's say that a request packet uses flags to determine what type of response is needed. The response packet would then need the value of those flags to be able to decode it properly. Previously, that was a limiting factor in the decodes. With super globals, such information from one packet may be carried to the next.

An example using Super Globals

Request:
	...
	DLNG 40000000 1 90 c2 Volume Request Flags:;
	 CEQU 0 1 0 14 Return the volume name with the volume number;
	 CEQU 1 1 0 14 Do not return the volume name with the volume number;
	s[1] = g[1];		// save the global 1's value in the super global
	...

Response:
	...
	DLNG 0 1 90 c2 Next Volume Number:;
	g[1] = s[1];			// get the super global's value in global 1
	if (g[1] == 0)
	{
		NCP::VolMntStructWithName;
	}
	if (g[1] != 0)
	{
		NCP::VolMntStruct;
	}
	...

Depending on what the value for the Volume Request Flags are in the request, the response will give a Volume Struct with a name or without a name. The super global saves what's in global 1 in the request and is able to use it in the response.

Examples

Decoder programming is much like assembly language programming with very long assembly instructions. The following examples serve to illustrate how we have programmed the decoding of some of the protocols.

This is a typical, simple decode instruction:

HWRD 0 2 90 c2 Checksum:;

This instruction translates to: decode the next 16 bits as hexadecimal, the high order bit of value is zero so prepend a "0x" (ignore remaining bits in value), store the 16 bits in global variable number 2, and format the display as: new line, label at column 2, in data label style, with the given string, data in plain style beginning at column 24.

Here is another example:

HBYT 0 1 90 c2 AppleTalk Type:;
CEQU 1 1 0 14 Short DDP;
TTST 0 0 0 0 Short DDP;
CEQU 2 1 0 14 Long DDP;
TTST 0 0 0 0 Long DDP;

These instructions do the decoding of the byte that contains the LAP type in an AppleTalk DDP packet. After displaying the value in hexadecimal, a translation string of "Short DDP" or "Long DDP" is displayed in the message style if the LAP type is equal to 1 or 2 respectively. Further, if either the type is 1 or 2, decode execution switches to a decoder named "Short DDP" or "Long DDP" respectively.

The best source of examples is the decoders we've provided with the product. If you're using Microsoft Windows you can view the decoders with a text editor such as NotePad or WordPad. If you're using MacOS you can view the decoders with a text editor such as BBEdit.

Creating Your Own Decoders

Remember, your decoder and string arrays should be uniquely named over the set of all decoder files. If you fail to do this, it is not a fatal problem, but it can be confusing because, most likely, only the first occurrence of an item will be found. Many protocol stacks have names or acronyms that are exactly the same. Choose your decoder names judiciously. Also, old decoder files must be moved out of the directory tree of the application.

Inevitably, you will need to link your decoders into the parsing stream of the decoder mechanism by changing at least one of the existing decoder files. Here are some hints for commonly used control points.

New 802.2 LSAP Types

1. Make a copy of the "decodes.dcd" file as a backup and move it to a safe place.
2. Open the original file.
3. Locate the last instruction in the "LSAP::Names" decoder which is a "TRTS".
4. Add a new "CEQU" instruction immediately before the last "TRTS" instruction.
5. Edit the instruction value to be the hexadecimal value of the new LSAP.
6. Edit the instruction string to be the name of the new 802.2 type.
7. Base the rest of the instruction on preceding "CEQU" instructions.
The next steps add the jump point to the new LSAP type. Usually there are two possibilities: two jump points, (one for the DSAP and one for the SSAP) or one jump point which requires that both the DSAP and SSAP have the same new value.
8. Locate the decoder called "802_2::Common".
9. Go to the bottom of the decode "802_2::Common", you will see a "802_2::Data", this is a branch instruction similar to:

TSUB 0 0 0 0 802.2 Data;
or
TSUB -802.2 Data;
Follow the the branch to the new decode "802_2::Data".
10. Locate the last instruction in the "802_2::Data" decoder which is a "DUMP".
11. If you want two jump points on either LSAP, add two "TEQU" instructions before the last "DUMP" instruction. One "TEQU" will test global 1 and the other will test global 2. Look above in the decode at the handling of 802.2 SNA for an example (instructions number 15 and 16).
12. If you want one jump point, only if the DSAP and SSAP are both the new LSAP value, then add an "SEQU" and a "TEQU" instruction before the last "DUMP" instruction. The "SEQU" instruction will test global 1 and set the previous test flag and the "TEQU" instruction will test global 2 and, using a special option (setting the high bit in the global column) for the "TEQU" instruction, branch to the named decoder if the values match to globals. Look above at the handling of IP for an example.
13. Edit the values for the instructions you added.
14. Edit the strings for the instructions you added to be the name of the new decode to handle the new LSAP.
15. Save and close the file.

New SNAP Types

1. Make a copy of the "decodes.dcd" file as a backup and move it to a safe place.
2. Open the original file.
3. Locate the decoder called "SNAP::Names".
4. Locate the last instruction in the "SNAP::Names" decoder which is a "TRTS".
5. Add a new "CEQU" instruction before the "TRTS".
6. Edit the instruction value to be the hexadecimal value of the new SNAP.
7. Edit the instruction string to be the name of the new SNAP type.
8. Base the rest of the instruction on preceding "CEQU" instructions.
9. Locate the decoder called "SNAP".
10. Locate the last "TEQU" instruction.
11. Add a new "TEQU" instruction after the

TEQU 80c5 2 0 0 VINES Echo;
instruction.
12. Edit the instruction value to be the hexadecimal value of the new SNAP.
13. Edit the instruction string to be the name of the new jump point, the decoder that decodes the new SNAP type.
14. Base the rest of the instruction of preceding "TEQU" instructions.
15. Save and close the file.

New IP Types

1. Make a copy of the "decodes.dcd" file as a backup and move it to a safe place.
2. Open the original file.
3. Locate the decoder called "IP Common".
4. Add a new "TEQU" instruction at the top.
5. Edit the instruction value to be the hexadecimal value of the new IP type.
6. Edit the instruction string to be the name of the new decoder that handles the IP type.
7. Save and close the file.

New TCP or UDP Types

1. Make a copy of the "decodes.dcd" file as a backup and move it to a safe place.
2. Open the original file.
3. Locate the decoder called "TCP::Ports_Str".
4. Add a new entry above the first entry which should be

0x7 | Echo;
that will test the source port number stored in global 2.
5. Edit the instruction value to be the hexadecimal value of the new TCP or UDP type.
6. Edit the instruction string to be the name of the new decoder that handles the TCP or UDP type.
7. Examine subsequent instructions until you find them repeated. These instructions are testing the destination port number stored in global 2.
8. Add a new entry below your previous entry that will test the destination port number stored in global 2.
9. Edit the instruction value and string just as before.
10. Save and close the file.

If your decoder work has value to other users of our products, we would be happy to distribute your decoders along with our own, giving you credit for your work.


Decoder Instructions

Instruction Value Global Increment Description
ADDG Value to add. Global to store result. If the high bit of the global is on then add value numbered global to global, i.e., global[glob_num] += global[value] instead of global[glob_num] += value. Add value to a specified global. 0
ANDG Value to AND. Global to AND. If the high bit of the global is on then and value numbered global with global, i.e., global[glob_num] &= global[value] instead of global[glob_num] &= value. 0 Logical AND value and a specified global.
AT01 If value is zero, the name table search will be made using zero as a net work number or as a LLAP address type depending on the media type. If value is set to 1, the search will be made assuming that the pointer is at the destination node address in a long DDP packet and it will look for the net number backwards accordingly. If value is set to 2, the search will be made assuming that the pointer is at the source node address in a long DDP packet and it will look for the net number backwards accordingly. Result displayed is stored in this global. 1 AppleTalk 1 byte node number. Display as an AppleTalk address. Also an attempt is made to find that node in the name table.. If a match is made, then the name will be displayed.
AT03 not used Result displayed is stored in this global. 3 AppleTalk 3 bytes. Display as an AppleTalk address. An attempt is made to find that address in the name table. If a match is made, then the name will be displayed.
ATLG not used Result displayed is stored in this global. 4 AppleTalk long. Display as an AppleTalk address. An attempt is made to find that address in the name table. If a match is made, then the name will be displayed.
BBIT Number of bits. Second highest bit signifies to use LSB order. Result displayed is stored in this global. Value number of bits. Display bits as binary.
BBYT not used Result displayed is stored in this global. 1 Display byte as binary.
BGLB not used Global to display. 0 Display a global in binary format.
BITO not used bit offset from byte is stored in this global location. 0 Get bit offset.
BLNG not used Result displayed is stored in this global. 4 Display a 32-bit integer in binary format as 32 binary digits with a leading '%' sign.
BREM not used Number of bytes remaining is stored in this global location. 0 Get number of remaining bytes of packet.
BST# Value to subtract from global Global to test bits specified in indexed string array with. 0 A str# resource with the following string name is loaded and the indexes in the entries are used as bit positions to test against the global.  For each entry if the bit is the string is displayed, otherwise the string in the next is displayed if the next entry is an un-indexed entry.
BWRD The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 2 Display a 16-bit integer in binary format as 16 binary digits with a leading '%' sign.
BYTO not used Byte offset from start of packet is stored in this global location. 0 Get byte offset.
CBIT Value to check against global. Global to check against value. If the global has the high bit set then the previous test must also be true before displaying the string. 0 Test bit indicated by value in the specified global and if set then the string is displayed. Bit numbers start with zero as the least significant bit.
CEQU Value to check against global. Global to check against value. If the global has the high bit set then the previous test must also be true before displaying the string. 0 Test value against a global. The string is displayed if equal.
CGTE Value to check against global. Global to check against value. If the global has the high bit set then the previous test must also be true before displaying the string. 0 If value is greater than or equal to the specified global then the string is displayed. If the instruction global has the high bit on then the previous test must also be true before displaying the string. (ie. global <= value)
CHR# If no global is specified, value is used for number of bytes to display. High bit signifies display as 7-bit ASCII, i.e., ignore the high bit of each byte. If specified, global is used determine how many bytes to display. Value or global  Display bytes as printing characters using ASCII.
CKSM Value 1 indicates an AppleTalk DDP checksum. Value 2 indicates an IPv4 header checksum. Value 3 indicates a TCP, UDP, ICMP, or IGMP checksum. not used 0 Verify checksums for various packet types and displays the correct checksum if the value contained in the packet is incorrect.
CLTE Value to check against global. Global to check against value. If the global has the high bit set then the previous test must also be true before displaying the string. 0 If value is less than or equal to the specified global then the string is displayed. (ie. global >= value)
CLSE not used not used 0 If the most recent test is false display the string.
CNEQ Value to check against global. Global to check against value. If the global has the high bit set then the previous test must also be true before displaying the string. 0 Test value against a global. The string is displayed if not equal.
CRLF not used not used 0 Insert a return or new line.
CST# Value to subtract from global Index into string resource 0 A str# resource with the following string name is loaded and an index (in a global) is used to get the string to be displayed. If there is a value it is subtracted from the global. If there is no such string then nothing happens, and the test result is set to false.
CSTR High bit signifies display as 7-bit ASCII, i.e., ignore the high bit of each byte. Second highest bit signifies that the string is in UNICODE. Length of the string (not including NULL terminator) is stored here. Length of the string plus 1 for NULL terminator. Display a C-style string. The string in terminated by a null character (byte value zero).
D64B High bit signifies whether to display as signed. The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 8 Display a 64-bit integer in decimal format. If the high bit of value is on then the data is displayed as a signed decimal, rather than unsigned. The second highest bit commands a byte and word swap (INTEL format).
DBIT Number of bits. High bit signifies to display as signed number. Second highest bit signifies to use LSB order. Result displayed is stored in this global. Value number of bits. Display bits as decimal.
DBYT High bit signifies to display as signed. Result displayed is stored in this global. 1 Display byte as decimal.
DECR If no global specified, the number of bytes to decrement by. If specified, holds the number of bytes to decrement by. Negative Global or Value number of bytes. Decrement the packet pointer by the global, or value, skipping backwards by the number of bytes specified.
DGLB High bit signifies whether to display as signed. Global to display. 0 Display a global in decimal format.
DIVG Value to divide by Global to store result. If the high bit of the global is on then divide value numbered global by global, i.e., global[glob_num] /= global[value] instead of global[glob_num] /= value. 0 Divide specified global by value.
DLNG High bit signifies whether to display as signed. The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 4 Display a 32-bit integer in decimal format.
DMPE If value is 0, dump all the remaining bytes if the packet. If value is 1, leave enough bytes for CRC. Any other value means to output that number of bytes. If specified, output the number of bytes contained within this global. Number of bytes output Display data in both hex and EBCDIC, side by side. Number of bytes is either in a global if specified, or in value, or is to the end of the packet.
DUMP If value is 0, dump all the remaining bytes if the packet. If value is 1, leave enough bytes for CRC. Any other value means to output that number of bytes. If specified, output the number of bytes contained within this global. Number of bytes output Display data in both hex and ASCII, side by side. Number of bytes is either in a global if specified, or in value, or is to the end of the packet.
DWRD High bit signifies whether to display as signed. The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 2 Display a 16-bit integer in decimal format.
EBC# If no global is specified, value is used for number of bytes to display. High bit signifies display as 7-bit EBCDIC, i.e., ignore the high bit of each byte. If specified, global is used determine how many bytes to display. Value or global Display bytes as printing characters using EBCDIC.
ENDS not used not used 0 End a SKIP block
ETHR not used not used 6 Six bytes as an Ethernet address. An attempt is made to translate the address into a DECnet address. Also an attempt is made to find that address and/or DECnet address in the name table. If a match is made, then the name will be displayed.
FCSC not used Result (checksum) is stored in this global location. 0 Calculates checksum based on packet media type.
FTPL Value 1 is for use with FTP, SMTP, and POP style replies. Value 3 is for TELNET style command and data. not used Number of bytes output Display data in both hex and ASCII, side by side. Number of bytes is determined by scanning for a command delimiter. Value 0 is for use with FTP, SMTP and POP style requests.
GBIT Number of bits to retrieve. Global location to store retrieved bits. 0 Take the number of bits specified in value and place them in the specified global without incrementing the packet pointer or displaying any information.
GBYT Byte offset from current location in packet. Global location to store retrieved byte. 0 Put a byte in the specified global without incrementing the packet pointer or displaying any information.
GLNG Byte offset from current location in packet. Global location to store retrieved long. 0 Put a 32-bit integer in the specified global without incrementing the packet pointer or displaying any information.
GSTR If the 3rd highest bit is set, it specifies to use the value as the value to be searched for. If nothing is specified, the default value searched for will the NULL. Byte offset from packet location up to where it found the value specified. 0 Get string length.
GWRD Byte offset from current location in packet. Global location to store retrieved word. 0 Put a 16-bit integer in the specified global without incrementing the packet pointer or displaying any information.
HBIT Number of bits. High bit signifies not to prepend "0x". Result displayed is stored in this global. Value number of bits. Display bits as hex.
HBYT High bit signifies not to prepend "0x". Result displayed is stored in this global. 1 Display byte as hex. Also useful for display or tests of greater than 4 bytes, where results have to be loaded in different globals.
HEX# If no global is specified, value is used for number of bytes to display. High bit signifies whether to prepend "0x". If specified, global is used determine how many bytes to display. Value or global Display bytes as hex.
HGLB High bit signifies whether to prepend "0x". Global to display. 0 Display a global in hexadecimal format.
HLNG High bit signifies whether to prepend "0x". The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 4 Display a 32-bit integer in hexadecimal format.
HWRD High bit signifies whether to prepend "0x". The second highest bit commands a byte swap (INTEL format). Result displayed is stored in this global. 2 Display a 16-bit integer in hexadecimal format.
INCR If no global specified, the number of bytes to increment by. If specified, holds the number of bytes to increment by. Global or Value number of bytes. Increment the packet pointer by the global, or value, skipping ahead by the number of bytes specified.
IPLG not used Result displayed is stored in this global. 4 Display an IPv4 address. An attempt is made to find that address in the name table. If a match is made, then the name will be displayed.
IPV6 not used not used 16 Display an IPv6 address. An attempt is made to find that address in the name table. If a match is made, then the name will be displayed.
LABL not used not used 0 A label only. The instruction string is used as a label and is displayed. The packet pointer is not incremented.
LSTS not used not used 0 List start. If a string is provided, a count will be appended to it and displayed. The count will be incremented. Count starts at 1.
LSTE not used Indicates end of list if greater than or equal to list count. 0 List end. Execution returns to the last LSTS, unless global is less than or equal to the count.
LSTZ not used Indicates end of list unless it's less than or equal to zero. 0 List end. Execution continues at the last LSTS unless global is less than or equal to zero.
MARK Index of string within the str# designated by the string field to use in future WHOA. Contains the reference point for linking request and response packets, usually transaction ID or port # etc. Entered into the cache with packet number and value and string fields. 0 MARK a value and this packet number for later usage in the WHOA instruction by logging the relevant parameters in a cache. See the more detailed overall explanation of MARK and WHOA threading, above.
MODG Value to mod by. Global to store result. If the high bit of the global is on then modulus value numbered global by global, i.e., global[glob_num] %= global[value] instead of global[glob_num] %= value. 0 Modulus specified global by value.
MOVE not used If the high bit of the instruction global is set then put value-numbered global into global. 0 Put value (or value contained within a global) in a specified global without incrementing packet pointer.
MULG Value to multiply by. Global to store result. If the high bit of the global is on then multiply value numbered global by global, i.e., global[glob_num] *= global[value] instead of global[glob_num] *= value. 0 Multiply value and a specified global.
NBNM not used 16th byte of the decoded name (the resource or service code) is stored in this global. Length of the name Display NetBIOS (reversible half-ASCII) name.
NOTG Value to NOT. Global to store result. If the high bit of the global is on then store value numbered global into global, i.e., global[glob_num] ~= global[value] instead of global[glob_num] ~= value. 0 Logical NOT a specified global.
ORRG Value to OR. Global to OR. If the high bit of the global is on then store value numbered global into global, i.e., global[glob_num] |= global[value] instead of global[glob_num] |= value. 0 Logical OR value and a specified global.
OSTP not used Result displayed is stored in this global. 4 4 bytes displayed as characters.
POPX not used Value popped from stack is stored in this global. 0 Pops one value from the stack and stores the value in the global specified.
PORT If value is set to 0, a 2-byte field is displayed as a TCP/UDP port. If value is set to 1, a 2-byte field is displayed as a NetWare port. Result displayed is stored in this global. 2 Used to display a port field. If value is set to 0, a 2-bit field is displayed as a TCP /UDP port. If value is set to 1, a 2-bit field is displayed as a Netware port. In any of the above cases, also try to find a match in the name table, and display the name if found.
PRTO If value is set to 1, a 2-byte field is displayed as an unsigned 16-bit integer depicting Ethernet Type II protocol type. If value is set to 2, a 1- byte field is displayed as an unsigned hexadecimal byte depicting the LSAP type (802.2). If value is set to 3, a 5-byte field is displayed as an 802.2 SNAP value in hexadecimal. Result displayed is stored in this global. If it's an 802.2 SNAP ID, then only the bottom 4 bytes are stored. If value is 0 or 1, increment is 2. If value is 2, increment is 1. If value is 3, increment is 5. Used to display a protocol field. An attempt is made to find that protocol in the name table. If a match is made, then the name will be displayed.
PSTR High bit signifies display as 7-bit ASCII, i.e., ignore the high bit of each byte. Length of the string (not including length byte) is stored here. Length of the string plus 1 for length byte. Display a Pascal-style string. The first data byte indicates the length of the string.
PUSH not used Global value to push onto the stack. 0 Pushes a value onto the stack.
SBIT Bit number to test. Global to test. 0 Test the bit specified by value in the specified global and remember for the next test. Bit numbers start with zero as the least significant bit.
SCMP Number of chars to compare. not used. 0 Compares the number of bytes specified by value field to the string specified in the string field. If equal, the test boolean flag will be set to true.
SEQU Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] == global[value] instead of global[glob_num] == value. 0 Check value against global, and set previous test if equal.
SGTE Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] <= global[value] instead of global[glob_num] <= value. 0 Check value against global, and set previous test if greater than or equal.
SGTX Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] < global[value] instead of global[glob_num] < value. 0 Check value against global, and set previous test if greater.
SHFL Amount to shift left. Global contains the value to shift. 0 Shifts the global value to the left the number specified in the value field.
SHFR Amount to shift right. Global contains the value to shift. 0 Shifts the global value to the right the number specified in the value field.
SKIP Number of instructions to skip. If the value is 0 then the value will be determined by ENDS.  If the high bit is set then skip if most recent test was false. If 2nd highest bit is set then do not skip.  If 3rd highest bit is set then skip.  not used 0 Skip over value number of instructions if most recent test was true. If the high bit of the value is on then skip if most recent test was false. This is an easy way to branch over a few instructions without having to transfer to other decode resources. Note: You can not skip backwards (no negative values permitted).
SLTE Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] >= global[value] instead of global[glob_num] >= value. 0 Check value against global, and set previous test if less than or equal.
SLTX Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] > global[value] instead of global[glob_num] > value. 0 Check value against global, and set previous test if less than.
SNEQ Value to check against global. Global to check against value. If the high bit of the global is on then compare value numbered global with global, i.e., global[glob_num] != global[value] instead of global[glob_num] != value. 0 Check value against global, and set previous test if not equal.
SUBG Value to subtract. Global to store result. If the high bit of the global is on then subtract value numbered global from global, i.e., global[glob_num] -= global[value] instead of global[glob_num] -= value. 0 Subtract value from a specified global.
TBIT Bit number to test. Global to test. If global has 0x100 set, then previous test must also be true before transferring. 0 If the bit number contained in value is set then branch to the named decoder. Bit numbers start with zero as the least significant bit.
TEQU Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Test value against a global and branch to the named decoder if they match.
TGTE Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 If value is greater than or equal to a global then branch to the named decoder. (ie. global <= value)
TGTX Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 If value is greater than a global then branch to the named decoder. (ie. global < value)
TIME If value is 1, format is AppleTalk AFP time. If value is 2, format is IP time. If value is 3, format is NTP time. If value is 4, format is ANSI time. If value is 5, format is SMB time. Result displayed is stored in this global (except in the case of SMB time). 4 (or 8, in the case of SMB time) 4 (or 8) bytes are displayed in hexadecimal and then are used to display the corresponding time.
TLSE not used not used 0 If most recent test is false then branch to the named decoder.
TLTE Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 If value is less than or equal to a global then branch to the named decoder. (ie. global >= value)
TLTX Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 If value is less than a global then branch to the named decoder. (ie. global > value)
TNEQ Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Test value against a global. If not equal then branch to the named decoder.
TNXT not used not used 0 Branch to the named decoder.
TRNG not used not used 6 Six bytes as an 802.5 Token Ring address. Also an attempt is made to translate the address into a DECnet address. Also an attempt is made to find that address and/or DECnet address in the name table. The bit for source routing information is ignored for such searches. If a match is made, then the name will be displayed.
TRTS not used not used 0 Return from a subroutine. The return is to the instruction following the last TSUB encountered.
TST# Value to subtract from global Index into string resource 0 A str# resource with the following string name is loaded and an index (in a global) is used to get the name of the decoder to be loaded. If there is a value it is subtracted from the global. If there is no such name, nothing happens, but test result is set to false.
TSB# Value to subtract from global Index into string resource 0 A str# resource with the following string name is loaded and an index (in a global) is used to get the name of the decoder to be loaded. The decoder that is loaded will return upon completion. If there is a value it is subtracted from the global. If there is no such name, nothing happens, but test result is set to false.
TSUB not used not used 0 Subroutine branch to the named decoder. Remember the current instruction's location for the TRTS instruction. Subroutine nesting is limited to 16 levels.
TTST not used not used 0 If the most recent test is true, branch to the named decoder. Will also do a TEQU if a global is specified.
XTST not used not used 0 Similar to TTST, but after branching to the named decoder, it will return to this location.
XBIT Bit number to test. Global to test. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TBIT, but after branching to the named decoder, it will return to this location.
XEQU Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TEQU, but after branching to the named decoder, it will return to this location.
XGTE Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TGTE, but after branching to the named decoder, it will return to this location.
XGTX Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TGTX, but after branching to the named decoder, it will return to this location.
XLTE Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TLTE, but after branching to the named decoder, it will return to this location.
XLTX Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TLTX, but after branching to the named decoder, it will return to this location.
XNEQ Value to check against global. Global to check against value. If global has 0x100 set, then previous test must also be true before transferring. 0 Similar to TNEQ, but after branching to the named decoder, it will return to this location.
XLSE not used not used 0 Similar to TLSE, but after branching to the named decoder, it will return to this location.
WHOA Default index of string within the str# designated by the string field to use in future WHOA. Upper 8 bits, if non-zero, indicate a global number where the packet number of the MARK is placed if a match is found. Contains the reference point for linking request and response packets, usually transaction ID or port # etc. Used to search the cache along with the string field number, retrieving the value field and packet number. 0 See the more detailed overall explanation of MARK and WHOA threading, above. If a packet type can not be determined from data within the packet itself, a cache is searched to determine if some earlier packet did a MARK instruction to give a clue as to how to decode this packet. If no such entry exists in the cache, a question mark is displayed at the bottom of the decode window while a default decode is provided or the user's input is necessarily requested or the previous choice is assumed depending upon the current mode of operation. When the question mark is displayed or any other choice has been made either manually or through the MARK instruction, clicking on the name or question mark displayed at the bottom of the window causes the user's input to be requested again. Any value selected by explicit user input will override any previous choices made through the MARK or other mechanisms. The string should contain the name of a str# resource that contains the names of the decode resource choices that may be used on the next part of the packet.

Private Instructions

Instruction Value Global Increment Description
PRV1 not used not used 0 Display packet timestamp.
PRV2 not used Result is stored in this global. 0 Display internal packet flags.
PRV3 not used Result is stored in this global. 0 Display internal packet status.
PRV4 not used Result is stored in this global. 0 Display packet length.
PRV5 not used Result is stored in this global. 0 Display packet slice length.
PRV6 not used Result is stored in this global. 0 Display 802.3 length field (as opposed to the Ethernet Type II protocol field located in the same location).
PRV7 not used not used 0 Reserved for future use.
PRV8 not used not used 0 Reserved for future use.

Data Formats

In every decode instruction the data format is one byte. It can be divided into two 4-bit sections: the high 4 bits signify the columnar location to display the data (the data location bits) and the low 4 bits signify the style (color, etc.) in which the data should be displayed (the data style bits).

Data Format Representation

Bit 7 6 5 4 3 2 1 0
Field Format Style

Data Location Field

Value Meaning
0x0 Display data immediately with no spaces.
0x1 Display data after a carriage return.
0x2 Skip 2 spaces, then display data.
0x3 Skip 4 spaces, then display data.
0x4 Display data beginning in column 4.
0x5 Display data beginning in column 8.
0x6 Display data beginning in column 12.
0x7 Display data beginning in column 16.
0x8 Display data beginning in column 20.
0x9 Display data beginning in column 24.
0xA Display data beginning in column 28.
0xB Display data beginning in column 32.
0xC Display data beginning in column 36.
0xD Display data beginning in column 40.
0xE Display data beginning in column 44.
0xF Display data beginning in column 48.

Data Style Field

Value Meaning
0x0 Plain data.
0x1 Layer label.
0x2 Data label.
0x3 header label (for use with PRVx instructions).
0x4 Message.
0x5 Invisible.
0x6 Data dump label.
0x7 Indent.
0x8 Unindent.
0x9 Unused.
0xA Unused.
0xB Unused.
0xC Unused.
0xD Unused.
0xE Unused.
0xF Unused.

Label Formats

In every decode instruction the label format is one byte. The label format byte can be divided into one 1- bit field (the highest bit) which tells whether a new line should precede the label (the newline bit), one 3- bit field that tells the columnar location to display the label (the label location bits), and one 4-bit field (the lowest bits) which tell the style (color, etc.) in which the label should be displayed (the label style bits).

Label Format Representation

Bit 7 6 5 4 3 2 1 0
Field Line Format Style

Label Newline Field

Value Meaning
0x0 No new line before label.
0x1 New line before label.

Label Location Field

Value Meaning
0x0 Display label immediately with no spaces.
0x1 Skip 2 spaces, then display data.
0x2 Skip 4 spaces, then display data.
0x3 Display label beginning in column 0.
0x4 Display label beginning in column 2.
0x5 Display label beginning in column 24.
0x6 Display label beginning in column 32.
0x7 Display label beginning in column 36.

Label Style Field

Value Meaning
0x0 Plain.
0x1 Layer label.
0x2 Data label.
0x3 Header label (for use with PRVx instructions).
0x4 Message.
0x5 Invisible.
0x6 Unused.
0x7 Indent.
0x8 Unindent.
0x9 Unused.
0xA Unused.
0xB Unused.
0xC Unused.
0xD Unused.
0xE Unused.
0xF Unused.

 


Instruction Index

A B C   D   E F G
ADDG BBIT CBIT CRLF D64B DMPE EBC# FCSC GBIT
ANDG BBYT CEQU CST# DBIT DUMP ETHR FTPL GBYT
AT01 BEEP CGTE CSTR DBRK DWRD     GLNG
AT03 BGLB CHR#   DBYT       GSTR
ATLG BITO CKSM   DECR       GWRD
  BLNG CLSE   DGLB        
  BREM CLTE   DIVG        
  BST# CNEQ   DLNG        
  BWRD              
  BYTO              
                 
H I L M N O P S  
HBIT INCR LABL MARK NBNM ORRG POPX SBIT SKIP
HBYT IPLG LSTE MODG NOTG OSTP PORT SCMP SLTE
HEX# IPV6 LSTS MOVE     PRTO SEQU SLTX
HGLB   LSTZ MULG     PSTR SGTE SNEQ
HLNG           PUSH SGTX SUBG
HWRD             SHFL  
              SHFR  
                 
T   W X          
TBIT TRAK WHOA XBIT          
TEQU TRNG   XEQU          
TGTE TRTS   XNEQ          
TGTX TSB#   XGTE          
TIME TST#   XGTX          
TLSE TSUB   XLSE          
TLTE TTST   XLTE          
TLTX TYPE   XLTX          
TNEQ     XNEQ          
TNXT     XTST