			 PBT's Preprocessor
			     version 1.21

			(C) 2002-2005 PEERSOFT


			    user's guide



Table Of Contents
_________________
1. Introduction
2. Using PBT's Preprocessor
2.1 Syntax
2.2 How it works
3. The PLL language
3.1 Script file format
3.2 File pointers
3.3 Replaceable parameters
3.4 Script commands
3.4.1 READBYTE, READWORD, READLONG and READVAR
3.4.2 READREAL
3.4.3 READSTR
3.4.4 READTIME
3.4.5 MOVEFOR, MOVEBACK and MOVETO
3.4.6 LOOP
3.4.7 GOTO
3.4.8 WRITE and WRITELN
3.4.9 EQU and BITEQU
3.4.10 IF
3.4.11 INCLUDE
3.4.12 QUIT
3.4.13 GOTOCOL
3.4.14 DESCRIBE
3.4.15 SET
3.4.16 DISPLAY
3.4.17 WRITETO
3.4.18 SAVEPOS and RESTOREPOS
3.4.19 ASM



1. Introduction

PBT's Preprocessor is a tool that makes it easy to create PBT scripts. All
script commands supported by PBT have completely different names and syntax,
thus making your work with PBT easier. Whereas PBT itself was designed to be
used by programmers and advanced users, PBT with its preprocessor makes it
easier to write scripts from scratch, consuming less time that was ever
required when developing, debugging and testing your scripts.

The main purpose of this documentation is to describe all aspects of PBT's
preprocessor and its programming language. Assuming that you have used PBT
for some time, this documentation is ideal for you to compare PBT's native
script language with PLL (PBT's List Language) used by the preprocessor.
For absolute novices who have no experience with PBT, each command includes
its description and there are some example scripts in this package written in
both PBT's native language and PLL.

As you could notice, PBT's preprocessor concentrates on interpreting and
translating scripts written for the 'L' command of PBT. This command lets
you list *any* data structure using its script language. Although the 'P'
command of PBT also uses script language for patching files, this language is
not too complicated and making a different preprocessor for it would not
definitely make your patching easier and more efficient.



2. Using PBT's Preprocessor

PBT's preprocessor is contained in a program file called PP.EXE. The
purpose of this executable file is to translate your PLL scripts into PBT's
native script language and then launch PBT for processing. Therefore, you
don't need to launch PBT separately. As soon as PBT finishes processing your
script, PBT's preprocessor deletes a temporary file containing
the translated script. However, if you want to preserve the translation, e.g.,
for debugging purposes, it's possible to bypass PBT's execution. In this
case, PBT's preprocessor translates your script written in PLL into PBT's
native script language and leaves the translation on disk.


2.1 Syntax

PP.EXE <datafile> <scriptfile> [outfile] [# <param1> [param2 ...]>]
or
PP.EXE - <scriptfile> [outfile]

<datafile> is the name of the data file to be processed by PBT. You must
specify this name in order to be able to execute PBT from PBT's
preprocessor. Virtual file names are allowed.

<scriptfile> is the name of the script file translated by PBT's
preprocessor into PBT's native script language. In order to differentiate
between these two script languages, we supply unique file names for all
script files contained in the PBT distribution package. File names ending
in .SCR are script files written in the PBT's native script language,
whereas those file names ending in .SCP are designed for the PBT's
preprocessor. However, it's up to you to decide whether to follow our
script naming convention or not.

[outfile] is the optional name of the output file. Supplying this file name
to PBT's preprocessor makes it possible to record results of its
translation to a file. After translation, you should be able to use this
output file as the script file for PBT itself.

[param?] are replaceable parameters (see below).


2.2 How it works

At startup, PBT's preprocessor collects command-line parameters. Then it
tests if the <datafile> exists. If you supply the [outfile], it is
created for writing the resulting script, otherwise a temporary file
called $TEMP$.SCR is created. The script in PLL is translated afterwards.
After the translation, PBT's preprocessor normally runs PBT with the
following command line:
PBT L <datafile> @outfile [# params]
where outfile is the name of the output file supplied to PBT's preprocessor
or $TEMP$.SCR and [params] are replaceable parameters.
However, if you replace the <datafile> with a dash (-), PBT's execution is
bypassed.
In the end, whether PBT was executed or not, if the temporary file was
created, it is now deleted. This is the reason you must provide the output
file name in order to preserve the result of translation.



3. The PLL language

PLL (PBT's List Language) is a high-level programming language. Its
commands are uniquely named to meet your needs and most commands can be
written in different ways by using alternate keywords.

PLL is definitely not a derivative of another programming language,
although you can see resemblances in some commands. However, most command
names are unique to PBT.

If a PLL command has arguments, they are separated from the command name by
a space and individual arguments are delimited by a comma. There are some
exceptions to these rules, though. The following argument types are used:
- keywords: these keywords give additional properties to the specific
  command.
- numbers: all numeric values are entered in decimal. If you want to use
  hexadecimal numbers, you must preface them with a dollar sign ($). This
  rule applies to all commands used in PLL that accept numbers.
- Quoted strings: a quoted string is a string of characters enclosed in
  apostrophes ('). PBT's preprocessor doesn't check or touch contents of
  quoted strings in any way and it's the matter of PBT to interpret quoted
  strings correctly.
  All characters inside quoted strings are assumed to be literal, meaning
  that they are not touched. However, escape sequences are an exception.
  Escape sequences begin with a backslash character (\) and depending on
  the following character, the escape sequence is replaced by various
  control codes as follows:
  \a - bell (ASCII 7), beeps the PC speaker
  \b - backspace (ASCII 8), moves the cursor one character to the left
  \f - form feed (ASCII 12), used as a page break
  \n - CR/LF (ASCII 13 and 10), starts a new line 
  \r - CR (ASCII 13), moves the cursor to the start of the line
  \t - tab (ASCII 9), moves the cursor to the next tab stop
  \nnn - decimal representation of a character (always 3 digits)
  \$nn - hexadecimal representation of a character (always 2 digits)


3.1 Script file format

A single line in a script file can contain commands, comments or both. The
maximum number of characters allowed on a line is 255. Number of lines in a
script file is not limited.

Commands can be written either in lower or upper case. You can write more
commands on a single line by using the caret symbol ("^") as the command
separator.

Comments must start with a semicolon (;) and can be placed anywhere on a
line. The rest of the line after the first semicolon is ignored.

All rules described above do not apply to quoted strings. Quoted strings,
as a whole entity, can hold *any* printable characters, even a semicolon or
a caret.

You can add spaces and tabs around commands and arguments to make your scripts
more readable. You can use as many spaces or tabs as you want - PBT's
preprocessor simply ignores them.



3.2 File pointers

File pointers tell PBT where it should begin reading/writing data. Each 
view area has its own file pointer. File pointers can be changed by moving 
around view areas using positional commands. Almost all commands designed 
for reading files also change file pointers upon completion, thus making 
sequential file reading possible. There are, however, a number of commands 
that do not change file pointers at all.



3.3 Replaceable parameters

Replaceable parameters make your scripts flexible and provide a way of 
communication between you as a programmer of scripts and users of your 
scripts. Replaceable parameters resemble command-line parameters used in 
DOS batch files but are limited to numeric values only. The count of 
replaceable parameters entered on the command line is limited to 9.

You enter replaceable parameters on the command line by adding a hash 
character ('#') to the end of the command line, surrounded by spaces and 
followed by parameters' values delimited by spaces. For example:
PP TEST.BIN SCRIPT.SCP # 3 4 5
executes PBT's Preprocessor with the script file SCRIPT.SCP, data file 
TEST.BIN and three replaceable parameters 3, 4 and 5.

From the programmer's perspective, replaceable parameters can be entered in 
many commands in places where numbers would normally appear. Parameters are 
numbered from 0 to 9 and when entered in scripts, are written as PARAM(1) 
to PARAM(9), respectively. Parameter 0 represents the actual count of 
parameters entered on the command line and can be written as PARAMCOUNT.
When designing scripts for usage with replaceable parameters, you must 
first decide how many parameters your script should accept and for what 
purpose. While writing lines of your script, you must also decide which 
commands will use constant numbers and which commands are desired to have 
some variables within them. For example, you might want to execute the 
HEXDUMP script provided in this package with variable starting offsets. In 
order to provide some real example for using replaceable parameters, the 
HEXDUMP script has been already modified to perform this task. You can 
execute it in the normal way without any replaceable parameters or with one 
parameter specifying the starting offset to list from.

As stated above, replaceable parameters cannot be used everywhere. For this 
purpose, all commands described below contain a listing of their arguments 
which support replaceable parameters.



3.4 Script commands

This section describes all commands used by PBT's preprocessor. A list of
alternate keywords is included in the command description as well. If there
are alternate keywords for the command name, they are listed at the beginning
of the command's section. If there are alternate keywords for individual
arguments, they are listed before the argument's description. If you have had
some experience with PBT already, you will appreciate PBT commands written in
parentheses placed just before argument descriptions. This will help you
compare differences in PLL and PBT's native script language.

Please note that command descriptions do not contain an explanation of
computer-related terms such as byte, BCD, numbering systems etc. This text
assumes you have some knowledge of these terms. If not, you can learn more
in some computer-related books or on the internet. This document describes
only the operation of PBT and its preprocessor, not a computer
architecture.



3.4.1 READBYTE, READWORD, READLONG and READVAR

PBT commands: B, W, L and V

Alternate keywords: none

Replaceable parameters: WIDTH, bitwise/arithmetical operations

Description:
These commands are designed to read and display integer numbers of various
sizes and formats. They work as follows:
1. READBYTE - read and interpret single byte
2. READWORD - read and interpret single word
3. READLONG - read and interpret single 32-bit integer number
4. READVAR - read and interpret variable-length integer numbers found in
   MIDI files

Arguments:
These parameters are used to affect the interpretation of integer numbers:
- BCD (B) - interpret integer numbers stored in BCD (Binary Coded Decimal).
  This applies to the READBYTE command only.
- BIGENDIAN (B) - interpret integer numbers stored using the big-endian format
  (applies to READWORD and READLONG only)
- SIGN, SIGNED (S) - interpret integer numbers as signed (all integer numbers
  are interpreted as unsigned by default)
- LEFT, LEFTJUSTIFY, LEFTALIGN (-) - justify numbers to the left. By default,
  all numbers are right-justified.
- WIDTH=x (x) - display all numbers as x characters, filling remaining
  positions with spaces or zeros (see the SET command)
- in addition, PBT supports the following bitwise/arithmetical operations:
  AND x (&x)	 - bitwise AND with mask x
  OR x (|x, Ox)	 - bitwise OR with mask x
  XOR x (^x)	 - bitwise XOR with mask x
  NOT		 - bitwise NOT
  SHL n (<n, Ln) - shift left n bits
  SHR n (>n, Rn) - shift right n bits
  ADD x (+x)	 - add x
  SUB x (Mx)	 - subtract x
  MUL x (*x)	 - multiply by x
  DIV x (/x)	 - divide by x
  MOD x (%x)	 - remainder (modulo) from dividing by x

These arguments can be mixed freely in any order. If no argument is
specified, integer numbers are interpreted as unsigned little-endian
numbers and no justification is performed.

Notes:
1. Multiple bitwise/arithmetical operations of the same type are not allowed
   (i.e. "READBYTE AND $FE,AND $FC").
2. When using arithmetical operations such as MUL, please take into 
   consideration the fact that PBT interprets results of these operations 
   in the same numeric range as specified by the reading command, i.e. when 
   using the READBYTE command and multiplying the value just read by 200,
   the arithmetic overflow is likely to occur. In this case, PBT won't 
   display the result as word, but as byte. This limitation may change in 
   the future. On the other hand, such a limitation can be beneficial for 
   you and is aimed to prevent you from writing erroneous scripts. You can, 
   however, decline this limitation by reading a word instead of byte, thus 
   extending the allowed numeric range, then mask out redundant bits, apply 
   your arithmetical operations, return the file pointer one location 
   back and you will get satisfactory results. This step-by-step process 
   outlined above can be realized in the following way:
   READWORD AND $FF,MUL 200
   MOVEBACK
3. If you enable 24-bit long integers support, the READLONG command reads 
   and interprets 24 bits instead of 32 bits.
4. When using bitwise/arithmetical operations in conjunction with the WIDTH 
   parameter, the WIDTH parameter should precede all these operations, 
   otherwise PBT's Preprocessor will paste the WIDTH value to a number used 
   in the last operation, for example:
   READBYTE AND 5,WIDTH=6
   results in the following PBT command: B&56
   which in turn uses mask 56 instead of 5.

See also:
EQU and BITEQU - interpret integer numbers using literal strings
SET RADIX - interpret integer numbers using various numbering systems
SET LONGSIZE - switch between 32-bit and 24-bit long integers
SET ZERO - justify with spaces or zeros
SET PROCESSING - stop interpretation and output of numbers



3.4.2 READREAL

PBT command: none, denoted by the first argument

Alternate keywords: READFLOAT

Replaceable parameters: WIDTH

Description:
This command allows you to read and interpret floating point numbers of
various sizes and formats.

Arguments:
The first argument is mandatory. It specifies the format of the floating
point number to be read and can be as follows:
- PASCAL (R) - real numbers used by Turbo Pascal
- SINGLE (G) - single-precision IEEE numbers supported by the 80x87 math
  coprocessor
- DOUBLE (D) - double-precision IEEE numbers supported by the 80x87 math
  coprocessor
- EXTENDED (X) - extended-precision IEEE numbers supported by the 80x87
  math coprocessor
- COMP (C) - BCD integer numbers supported by the 80x87 math coprocessor
- MSSINGLE (MG) - single-precision floating point numbers used by earlier
  versions of BASIC compilers and interpreters developed by Microsoft corp.
- MSDOUBLE (MD) - double-precision floating point numbers used by earlier
  versions of BASIC compilers and interpreters developed by Microsoft corp.

The following arguments are optional:
- LEFT, LEFTJUSTIFY, LEFTALIGN (-) - justify numbers to the left. By
  default, all numbers are right-justified.
- WIDTH=x.y (x.y) - the x value specifies the width of the display field.
  If the y value is also specified, it determines the number of digits
  displayed after the decimal point.

These two arguments can be specified in any order. If they are not
used, numbers are displayed in the scientific notation (i.e. 1.53049E-3.)

See also:
SET ZERO - justify with spaces or zeros
SET PROCESSING - stop interpretation and output of numbers



3.4.3 READSTR

PBT command: S

Alternate keywords: READSTRING

Replaceable parameters: LEN

Description:
READSTR can read and interpret various character strings. Strings can be
stored using different data formats.

PBT supports all string storage methods I know. These methods are denoted
by the first argument of the READSTR command and can be as follows:
- PASCAL (P) - interpret strings stored in the format used by the Pascal
  programming language. The first byte of these strings indicates their
  length, further bytes are actual contents.
  Normally, PBT reads just the number of bytes needed to interpret this
  string. However, you can use the "LEN=x" subargument to indicate
  the correct amount of data to be read, even if the actual string length
  is smaller. This can be used to read files created by Turbo Pascal
  programs as typed files. These files contain records of a fixed length.
  To create a fixed-length record, strings must be written in their maximum
  length assumed by a programmer. As the result, strings can occupy 65
  bytes in the file although their actual length is 30 characters. For
  these records to be read correctly, you specify the assumed maximum
  string length as the x value and PBT then reads the whole field but
  displays as many characters as the first byte indicates. For an example
  of usage, see the LCSHDR.SCP script file. You will see that LCS
  descriptions are stored just this way.
- NULL, C (N) - interpret strings terminated by the null character (ASCII
  value 0). These strings are used in many applications written in C and in
  many services provided by DOS.
- DOLLAR, DOS (D) - interpret strings terminated by a dollar sign ($). These
  strings can be seen only in programs which use a service of DOS
  that displays strings terminated by the dollar sign.
- LEN=x (x) - interpret strings which have no special format and are stored
  as a stream of consecutive characters. The x value specifies the number of
  characters to be read and displayed.

See also:
SET DISPLAYMODE - modes of displaying strings
WRITE, WRITELN - displaying quoted strings
EQU and BITEQU - interpreting integer numbers using literal strings
DESCRIBE - describing a LCS/EXE file



3.4.4 READTIME

PBT command: T

Alternate keywords: READDATE

Description:
Reads the date and time record. This is a 4-byte record used by DOS to
store packed date and time in a directory. Although this record could be
read by the READLONG command and unpacked using the AND, SHL and SHR
arguments, this is more convenient. Moreover, in the time of implementing
this feature, PBT was not able to mask out individual bits using AND, SHL
and SHR operations.

This command just reads this record from a file and stores it in its
internal variables. You must display individual components by using the
DISPLAY command. For an example of usage, see DIRLIST.SCP.

Arguments: none

See also:
DISPLAY TIME - display stored time (hour, minute, second)
DISPLAY DATE - display stored date (day, month, year)



3.4.5 MOVEFOR, MOVEBACK and MOVETO

PBT commands: +, -, =

Alternate keywords: none

Replaceable parameters: n

Description:
These commands can be used to move to a specific location in the current
view area. Whereas the MOVETO command moves to an absolute location, other
two commands move forward and backward by a specified number of locations.

Arguments:
- n (n) - move to the n-th location or by n locations (n can be an integer
  number up to 32 bits)
- BYTE, BYTEDISP (B) - read a single byte-size integer number from the
  current view area and use it as the n value
- WORD, WORDDISP (W) - read a single word-size integer number from the
  current view area and use it as the n value
- LONG, LONGDISP (L) - read a single long-size integer number from the
  current view area and use it as the n value
- reg (reg) - jump to a location determined by the value of the specified
  register (acceptable registers are AX, BX, CX, DX, SI, DI, BP, DS, ES and
  FL - flags)
- reg:reg (reg:reg) - as above but interpret both registers as if it was a
  memory location in the segment:offset format (used primarily when reading
  memory). This two-register form can be used with the MOVETO command only.
- EOF (E) - jump to the end of the current view area. Applies to the MOVETO 
  command only.

If no arguments are specified, commands behave as follows:
- MOVEFOR - move one location forward
- MOVEBACK - move one location backward
- MOVETO - move to the first location in the active view area

Notes:
1. If you enable 24-bit long integers support, the LONG/LONGDISP 
   modifier reads just 24 bits to determine the new location.
2. If you use one of the BYTE/BYTEDISP, WORD/WORDDISP or LONG/LONGDISP 
   modifiers or register names in the view area 1 (registers), PBT reads
   contents of	registers as instructed by you but the actual movement
   command is  performed in the view area used previously. This behavior
   can be  confusing, especially for beginners, but you can ask yourself if
   it  makes sense to jump around 20 bytes of register space this way.
3. PBT automatically converts 24- and 32-bit pointers to linear addresses if 
   the following conditions are true:
   a) the MOVETO command is used
   b) the LONG/LONGDISP modifier is applied
   c) you are accessing the $MEMORY$ virtual file

See also:
DISPLAY OFFSET - display the current view area offset
SAVEPOS - save current view area position
RESTOREPOS - restore saved view area position
SET LONGSIZE - switch between 32-bit and 24-bit long integers



3.4.6 LOOP

PBT command: J

Alternate keywords: none

Replaceable parameters: n

Description:
Jump to a label when a condition is true.

Arguments:
The first argument determines the condition and can be as follows:
- EOF (E) - jump if not at the end of the current view area
- n (n) - jump n times
- COUNTER (C) - jump using a pre-established counter (see notes below)

The second argument specifies a label to jump to. The label must be defined
somewhere in a script file. You define the label by preceding its name by
a colon (like :loop.) Labels can be as long as you want but only the first
8 characters are significant. As a result, if you use two labels whose
names differ in the ninth character, PBT will report an error saying that
the specific label is duplicated. Labels must be composed of alphabetical
characters or numbers only. For an example of using the LOOP command and
labels, see HEXDUMP.SCP.

Loops can be nested. A maximum of 50 nested loops are allowed. PBT can 
handle up to 500 loop references, which include labels defined and labels 
used in the LOOP and GOTO commands. It means that if you define 250 labels, 
you can reference all of them in commands but if you define 500 labels, PBT 
will have no room to store references to them. 

Notes:
1. While creating counting loops, you may reach the end of the file 
   easily. In that case, PBT will exit the loop prematurely without 
   issuing an error message. This can be particularly useful when you 
   don't know the file size in advance. This trick is used in the 
   HEXDUMP example script. While this behavior can be useful in many 
   situations, it has also some drawbacks:
   - If you insist on completing all loop iterations, you must prevent 
     PBT from detecting the end of the file, for example, by moving 
     the file pointer one location back just before the condition test 
     occurs.
   - Bear in mind that PBT issues the error message when trying to read	
     multi-byte data unless you try to read strings with the maximum 
     length specified in the command such as "S16". In this case, PBT 
     will read only the number of characters available without 
     issuing the error message.
2. The COUNTER keyword is used to loop commands by a certain number of 
   iterations that is, however, unknown to you at the time of writing your 
   script. The loop count is assumed to be part of data structures listed 
   by your script. If this applies to you, create the counting loop by 
   following this outline:
   a) Move to a location which contains a number of items in the structure.
   b) Use the "SET COUNTER" command to load a loop counter with the loop 
      count. You can instruct PBT to read the loop count as a byte, word or 
      long integer (24- or 32-bit). While PBT establishes the loop counter, 
      it automatically adjusts the file pointer as in other data reading 
      commands.
   c) Move to a location where PBT should begin reading and interpreting 
      items of the data structure.
   d) Establish a loop point by defining a label.
   e) Perform commands needed to interpret your data.
   f) Issue the "LOOP COUNTER,label" command.

Final note: when using counting loops with the constant loop count, the 
	    number of iterations is limited to 65535. However, counting 
	    loops with the unknown number of iterations can loop up to 
	    2,147,483,647 times! 

See also:
SET COUNTER - establish a loop counter
GOTO - unconditional jump
IF - execute commands if a condition is true



3.4.7 GOTO

PBT command: JD

Alternate keywords: none

Description:
Jump unconditionally to a label specified by the first argument. The label
must be defined somewhere in a script file.

See also:
LOOP - conditional looping
IF - execute commands if a condition is true



3.4.8 WRITE and WRITELN

PBT command: none, the whole quoted string is used as the command

Alternate keywords: none

Description:
These two commands write text strings to the screen. They work much like
their Pascal counterparts:
1. WRITE - write a text string to the screen
2. WRITELN - write a text string to the screen and append CR/LF characters,
   thus moving cursor to the start of the next line

Arguments:
- a quoted string to be displayed

Issuing the WRITELN command without an argument simply starts a new line.

See also:
GOTOCOL - go to a specific screen column
SET ANSI - set usage of the ANSI driver



3.4.9 EQU and BITEQU

PBT commands: E, EB

Alternate keywords: none

Replaceable parameters: n

Description:
1. EQU - replace byte-sized integer numbers with literal strings
2. BITEQU - replace individual bits of a byte-sized integer number with
   literal strings

These two commands are used to:
- define equates (assign strings to individual values)
- clear equates (erase all definitions)
- enable equates usage
- disable equates usage

Equates are processed when you issue the READBYTE command. PBT reads a
single byte and then sees if equates are allowed. If both byte and bit
equates are enabled at the same time, bit equates are ignored. Before any
equates can be processed, PBT converts the value just read from the BCD
notation if necessary and optionally applies any bitwise/arithmetical operations
if requested by a user.

Byte equates processing involves these actions:
1. PBT checks if there is a literal string assigned to the value just read.
2. If so, it then checks if there is any request to justify it.
3. Finally, a literal string is displayed.

Bit equates processing involves these steps:
1. PBT tries to process each bit of the value. If the LEFT keyword is not
   specified, it goes from bit 0 to bit 7, otherwise the order of bit
   processing is reversed.
   When no string is defined in the current bit position, PBT does not
   display anything for the current bit.
2. If a bit is set, PBT displays the string associated to its position in a
   byte, optionally justifying it with spaces.
3. If a bit is not set, PBT sees if a special bit 8 is associated with any
   string. If so, this string is displayed, also justified if desired.

Arguments (identical for both commands):
- CLEAR (C) - erase all equates
- ON, ENABLE (E) - enable equates processing
- OFF, DISABLE (D) - disable equates processing
- n,s (n,s) - assign a quoted string s to a value n

Note: All strings defined as equates are justified to the left. Strings are
      always justified with spaces. Zero justification is not allowed.

Limitations:
- Strings used for byte equates can be no more than 20 characters in length.
- Strings used for bit equates have their maximum length restricted to 10
  characters.

See also:
READBYTE - interpret byte-sized integer numbers
SET AUTOEQU - automatic mapping of ASCII characters to byte equates



3.4.10 IF

PBT command: I

Alternate keywords: none

Replaceable parameters: arg1, arg2

Description:
Executes a command or a set of commands if a condition is true.
PBT's preprocessor supports two forms of the IF statement:
1. IF [NOT] arg1 = arg2 commands [ELSE commands]
2. IF [NOT] arg1 = arg2 THEN
   commands
   [ELSE
   commands]
   ENDIF

Let's look at the general principle used by the IF statement:
1. PBT reads a single value from the input file. The size of the value is
   determined by arg1 and can be as follows:
   - BYTE (B) - read a single byte
   - WORD (W) - read a single word
   - LONG (L) or a replaceable parameter - read a 32-bit integer value
2. If this value matches arg2 (or doesn't match arg2 and the NOT keyword is
   used), commands following arg2 are executed.
3. If the value does not match arg2 (or matches arg2 and the NOT keyword is
   used), all commands following the ELSE keyword are executed if the ELSE
   part is present. Otherwise, nothing happens.

Notes:
1. Square brackets used in the IF command syntax description denote
   optional items.
2. IF statements can be nested.
3. The first form of the IF statement is used in cases you want to execute
   only a few commands. On the other hand, if you have more commands to be
   executed or you are using nested IF statements, it's better to use the
   second form.
4. If using the second form, you must not enter any commands after the THEN
   or ELSE keywords on the same line.
5. Also note that if using the second form, you close the entire IF
   statement by issuing the ENDIF command.
6. You can use quoted strings enclosed in apostrophes in place of ARG2 for 
   better readability of your scripts. Quoted strings must be no longer 
   than 1 characters if comparing bytes, two characters if comparing words, 
   and four characters if comparing long words. Quoted strings represent a 
   perfect copy of the file image.
7. Whenever PBT reads a value from the current view area in order to 
   compare it against a value supplied by you, it stores the value into a 
   temporary buffer as if reading/interpreting numbers.
   This is a feature previously undocumented and it allows you to store the 
   value in another view area using the WRITETO command.

For complete PBT syntax, see PBT's help screen.
For examples of usage, please refer to script files included.

See also:
LOOP - creating conditional loops
GOTO - unconditional jump



3.4.11 INCLUDE

PBT command: @

Alternate keywords: none

Description:
Reads and interprets another script file as if it were a continuation of
the current script file. INCLUDE commands can be nested. After processing
the included script file, processing continues with the next command after
the INCLUDE command.

Note: although PBT has its @ command for including files, PBT's
      preprocessor performs this action itself in order to process all
      subsequent script files as well. However, the result is not written in
      separate script files.

Arguments:
- a quoted string determining the script file name



3.4.12 QUIT

PBT command: Q

Alternate keywords: none

Replaceable parameters: error code

Description:
Quits the current session. All scripts included subsequently are 
terminated. Control is passed to DOS or another program from which PBT was
called, e.g.  PBT's preprocessor.

Arguments:
- If you specify a number in the range 0 - 255, it is returned to the 
  parent process as the ERRORLEVEL value. If you issue the QUIT command with
  no arguments, zero is returned. Arguments can be used to signal various
  errors.

The QUIT command is most often used in the IF command to terminate script
execution under some condition.

See also:
IF - conditional execution of commands



3.4.13 GOTOCOL

PBT command: $C

Alternate keywords: none

Replaceable parameters: n

Description:
Moves the cursor to a specific screen column.

Arguments:
- n (n) - specifies a screen column from 1 to 80

Note: this command is included in PBT because you can create various
   listings and reports with it. For better screen output, this command
   provides the ability to create tables by placing data values at specific
   screen locations, thus making your listing representative.

See also:
SET ANSI - set usage of the ANSI driver



3.4.14 DESCRIBE

PBT command: $D

Alternate keywords: none

Description:
Allows you to describe your LCS/EXE files. When you convert your scripts or
LCS files to executable files, you will see your descriptions when you run
EXE files without parameters. Your EXE files can be made descriptive also
for others this way.

Arguments:
- a quoted string used as a description.

Note: you can create multi-line descriptions by using multiple DESCRIBE
      commands in one script. All but the last description line must be
      terminated by the \N escape sequence in order to start a new line.
      All lines concatenated together must not exceed 255 characters.



3.4.15 SET

PBT command: none, each variable has its own command

Alternate keywords: none

Replaceable parameters: allowed for the RADIX variable only

Description:
This command is used to set various internal variables used by PBT. This
way you can influence PBT's behavior in many commands.

Arguments:
Each variable can be assigned a value by specifying its name and a new
value, separated from its name by a comma. Some variables have different
keywords by which they can be identified, also some values can be written
in different ways. There are also variables which cannot be assigned a 
value and accessing them turns some options on.
A list of usable variables follows:
- RADIX, BASE (O) - set a new output base to a value specified. Numbers are
  converted from decimal to this new base in all commands that support
  interpreting integer numbers. Real numbers are not converted. The
  output base can be from 2 to 36, default 10.
- DISPLAYMODE: controls the way strings are to be displayed. These values
  are permitted:
  a) ALL ($S0) - display all characters (default)
  b) REPLACE, CTLREPLACE ($S1) - replace control characters (ASCII 0 - 31)
     by spaces
  c) REMOVE, CTLREMOVE ($S2) - remove control characters completely
- ZERO, ZEROJUSTIFY ($Z1 or $Z0) - instructs PBT whether to justify numbers
  with zeros (ON) or spaces (OFF) (default).
- AREA, VIEWAREA ($A) - selects one of the following view areas:
  a) FILE (0) - view the input file (default)
  b) REGS, REGISTERS (1) - view registers
  c) BUFFER (2) - view a temporary buffer
  d) PREV, PREVIOUS (P) - select the view area used previously
- PROCESS, PROCESSING ($V0 or $V1) - the OFF value says that numbers are not
  to be processed and displayed. The ON value returns to the normal state when
  PBT processes and displays all numeric values. Processing involves these 
  actions:
  - Converting from BCD/swapping byte order
  - Performing bitwise/arithmetical operations
  - Reading justification options/flags
  - Bit/byte equates processing
  - Converting to a different radix
  - Converting numeric value to a string of digits
  - Formatting the string of digits for output
  - Displaying the string of digits
  All PBT versions up to 2.21 inhibited all these actions. Since version 
  2.22, PBT inhibits all but the first three actions listed above. You can 
  thus perform bitwise/arithmetical operations and convert numbers even if 
  processing is turned off.
- LONGSIZE ($L) - enable (3) or disable (4) 24-bit long integers support. 
  By default, 32-bit long integer numbers are used. However, if a need 
  arises, e.g. when reading *.VOC sound files, PBT has support for these 
  24-bit long integers built-in. At the time of writing these lines, PBT 
  supports 24-bit long integers in the READLONG, MOVEFOR, MOVEBACK, 
  MOVETO and LOOP commands.
- SET COUNTER,BYTE|WORD|LONG ($UB, $UW, $UL) - establish a loop counter by 
  reading its value from the active view area as byte, word or long 
  integer. For more information, see the LOOP command.
- ANSI (/A) - uses ANSI escape sequences for moving to the specific screen
  column. As a result, when you redirect PBT's output to a file, it will be
  displayed correctly if you are using the ANSI driver.
- PAUSE (/P) - ensures that you won't miss anything when seeing results of
  your scripts onscreen. It displays the "-- More --" prompt at the last
  line of the screen and waits until you read all output entirely and press
  any key to continue.
- QUIET (/Q) - prevents error messages from being displayed, still returning
  the error code.
- SCRAMBLE (/S) - by using this switch, you can scramble your LCS modules
  and scripts contained in the EXE file. Scrambling allows you to add more
  security to your scripts to prevent some hackers from disassembly. 
  Scripts can be normally used even if scrambled.
- DEBUG (/D) - allows you to add so called "debug info" to your scripts.
  Debug info contains file names of your scripts and line numbers for all
  script lines. If your LCS or EXE file has debug info present, you will
  see complete error messages with file names and line numbers. Debug info
  does not contain label names and cannot be therefore useful for script
  disassembly. If you use the SCRAMBLE option, debug info is also
  scrambled.
- AUTOEQU (/E) - assigns characters to all byte equates at startup depending 
  on their ASCII values, i.e. a value of 65 will read as the capital 'A'. This
  can be useful when trying to display encoded strings.

Note: At the start of a script, you are in the view area 0 (the input file).
      Normally, you won't use other view areas unless you are using machine
      instructions to extend abilities of your scripts. In the latter case,
      you will need to read registers' contents and also a temporary buffer if
      used by you. Other view areas behave much like files and can be read and
      interpreted by all PBT commands.

See also:
WRITETO - writing to different view areas
ASM - writing assembly language instructions
EQU and BITEQU - interpreting integer numbers using literal strings
LOOP - conditional looping



3.4.16 DISPLAY

PBT command: none, each item has its own command

Alternate keywords: none

Replaceable parameters: allowed for the OFFSET keyword only

Description:
Displays various items. The first argument denotes the main item name,
further arguments specify other parameters. Arguments can be separated
either by a comma or a space. In the listing below, we separate all items
by a space. Where more synonymous keywords appear for a single argument,
they appear without spaces following each other and separated by commas.

Arguments:
- NAME FILENAME ($F0) - name of the input file without the path
- NAME FULL ($F1) - a fully-qualified name of the input file
- OFFSET WIDTH=x ($Ox) - current file position (offset) displayed to x 
  hexadecimal digits, unused digit positions are filled with spaces or 
  zeros (see "SET ZERO" for details)
- DATE DAY ($T0) - day from the date and time record
- DATE MONTH ($T1) - month from the date and time record
- DATE YEAR ($T2) - year from the date and time record
- TIME HOUR ($T3) - hours from the date and time record
- TIME MIN,MINUTE ($T4) - minutes from the date and time record
- TIME SEC,SECOND ($T5) - seconds from the date and time record

See also:
READTIME - read the date and time record



3.4.17 WRITETO

PBT command: $W

Alternate keywords: none

Description:
Writes a value to the specific view area (even file!). The whole process
can be as follows:
- First, switch processing of values off by using the SET PROCESS,OFF
  command.
- Then, use any of the READ? commands to read a number.
- Move to a location where data should be written, optionally changing the 
  view area.
- Issue the WRITETO command.

Arguments:
- FILE (0) - write to a file
- REGS, REGISTERS (1) - write to registers
- BUFFER (2) - write to a temporary buffer

Note: as shown above, WRITETO writes the binary representation of a number
      read by the last READ? command to the specific view area at its
      current position. The view area position is not changed. For an
      example of usage, see CMOS.SCP.

See also:
SET PROCESS - set processing and output of numbers on/off
SET VIEWAREA - set the active view area
ASM - writing assembly language instructions



3.4.18 SAVEPOS and RESTOREPOS

PBT commands: $P0 and $P1

Alternate keywords: none

Description:
1. SAVEPOS - saves current position in the active view area
2. RESTOREPOS - restores saved position

Arguments: none

Note: When restoring the saved position, you must be switched to the same 
      view area you used before saving the position.

For an example of usage, see HEXDUMP.SCP.

See also:
SET VIEWAREA - set the active view area



3.4.19 ASM

PBT command: $M

Alternate keywords: none

Description:
Allows you to enter assembly language instructions within your scripts.
PBT's preprocessor then assembles them and what PBT gets are
machine language instructions in hexadecimal notation. A typical usage is
as follows:
ASM
inst1
inst2
...
END

As you can see, all assembly language instructions are enclosed by the ASM
and END statements. However, sometimes you may want to execute a single 
instruction repeatedly throughout your scripts when using registers to 
simulate variables in programming languages. In that case, you will 
obviously take advantage of the shorter form as follows:
asm inst1 ^ inst2 ^ ...

As you can see, this shorter form does not require any END statement be 
present. It must, however, occupy just one line and instructions must be 
separated by the command separator.

Arguments: none

At startup, before any script command is executed, PBT automatically fills 
all registers with zeros.
Before PBT executes a machine language routine, it loads values from PBT's
registers (view area 1) to actual CPU registers. The order of
registers in the view area 1 is as follows: AX, BX, CX, DX, SI, DI, BP, DS,
ES and FL (Flags). PBT also gives you a temporary buffer which is 512 bytes
long and its address is in DS:SI.

When PBT prepares machine instructions for execution, it automatically
appends the RETF instruction to the end of the routine. If you return from
your routines another way, you must, however, use the RETF instruction to
return to PBT, otherwise PBT crash is likely to occur.

PBT can execute any instruction your CPU supports. However, PBT's
preprocessor can assemble only instructions supported by the 8086 CPU and
the 8087 FPU. Also, the following 80186/80286 instructions are supported:
- Shift and rotate instructions with an immediate value other than 1
- PUSHA, POPA, INSB, INSW, OUTSB and OUTSW instructions

This manual is not intended to teach you assembly language, however, some
aspects should be noted:
- No symbols referring data can be used, only labels ending with a colon
  can be defined and then used in jump or call instructions. If you need to 
  store data, the temporary buffer can be used.	
- Hexadecimal numbers must be preceded by a dollar sign ($).
- The DB pseudo-instruction is supported.
- Segment override prefixes must be entered separately before 
  the instruction, i.e. "ES: Mov [SI],AL" instead of "Mov ES:[SI],AL".
- These keywords are supported: BYTE, WORD, DWORD, QWORD and TBYTE, 
  optionally followed by PTR.
- Quoted strings in place of immediate values are supported, as in:
  Mov BL,'A'

After successful return from the routine, PBT writes all important
registers to the view area 1. The temporary buffer's contents are preserved
all the time PBT is running, so you can read and modify it freely and you
will find your changes whenever you use it again.

To fully support manipulations with registers and the temporary buffer,
there are commands for changing view areas, turning processing of numbers
on/off and writing your changes back. For an example of usage, see
CMOS.SCP.

See also:
SET VIEWAREA - switch active view area
SET PROCESSING - turn numeric processing on/off
WRITETO - write to view areas


