                                     
                                     
                                     
                                     
                                     
                                     
                                     
                            PIC Macro Assembler
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                                     
                        microEngineering Labs, Inc.














Copyrights and Trademarks
                                     
Copyright 1995, 1997 microEngineering Labs, Inc.

Parallax is a trademark of Parallax, Inc.
PIC is a Registered Trademark of Microchip Technology, Inc.



Disclaimer of Liability

microEngineering Labs, Inc. is not responsible for special, incidental, or
consequential damages resulting from any breach of warranty, or under any
legal theory, including lost profits, downtime, goodwill, damage to or
replacement of equipment or property, or any costs for recovering,
reprogramming, or reproducing any data used with microEngineering Labs'
products.







                             TABLE OF CONTENTS
                                     

1. Assembler Overview

2. Command Line Options
  2.1. Usage
  2.2. The PM Environment Variable
  2.3. Options
     2.3.1. Option -C
     2.3.2. Option -D
     2.3.3. Option -ELext
     2.3.4. Option -EMext
     2.3.5. Option -EOext
     2.3.6. Option -ESext
     2.3.7. Option -EIext
     2.3.8. Option -G#
     2.3.9. Option -Ipath
     2.3.10. Option -Lname
     2.3.11. Option -OB
     2.3.12. Option -OH
     2.3.13. Option -Q

3. Pseudo-Ops
  3.1. CODE
  3.2. DATA
  3.3. EEPROM
  3.4. ABS
  3.5. ORG
  3.6. DS
  3.7. DB
  3.8. DW
  3.9. EQU
  3.10. =

4. Conditional Assembly
  4.1. IF
  4.2. ELSEIF
  4.3. ELSE
  4.4. ENDIF
  4.5. IFDEF
  4.6. IFNDEF
  4.7. IFB
  4.8. IFNB

5. Macro Facility
  5.1. REPT
  5.2. IRPC
  5.3. IRP
  5.4. MACRO
  5.5. LOCAL
  5.6. EXITM
  5.7. ENDM

6. File Controls
  6.1. INCLUDE
  6.2. MACLIB

7. File and Listing Controls
  7.1. TITLE
  7.2. PAGE
  7.3. LIST
  7.4. NLIST
  7.5. MTLIST
  7.6. NMTLIST
  7.7. CLIST
  7.8. NCLIST
  7.9. LALL
  7.10. XALL
  7.11. SALL

8. Device Controls
  8.1. DEVICE
     8.1.1. Fuse Specifier
     8.1.2. Core Specifier
     8.1.3. Reserved Options
  8.2. ID
  8.3. RESET

9. Expressions
  9.1. Calculations
  9.2. Operators
     9.2.1. Bit Extension
     9.2.2. Modulus
     9.2.3. Shift Right
     9.2.4. DEF & REF
  9.3. Numeric Constants
  9.4. String Constants
  9.5. List Quoting
  9.6. Identifiers
     9.6.1. Identifiers Starting with ':'
     9.6.2. Identifiers Starting with '$'
     9.6.3. Identifiers Starting with '_'
     9.6.4. Identifiers Starting with '@'
  9.7. System Variables
     9.7.1. $
     9.7.2. DEVICE

10. File Formats
  10.1. Source File
  10.2. Map File
  10.3. Binary Output File
  10.4. Merged Intel HEX File
     10.4.1. PIC16C5x Device Descriptor
     10.4.2. PIC16Cxx Device Descriptor
  10.5. Symbol Table File
  10.6. Listing File

11. Assembling Existing Parallax Code

12. Warnings

13. Errors

14. Fatal Errors

15. Internal Errors

16. Microchip Instruction Set
  16.1. Summary of Microchip Instructions

17. Parallax Instruction Set
  17.1. Summary of Parallax Instructions
  17.2. Parallax Instruction Set Reference



1. Assembler Overview

Compatibility
     Microchip & Parallax Instruction Sets
     Microsoft Compatible Macros
     Supports all 12-bit (16C5x) and 14-bit (16Cxx) PICs

Operation
     Two-Pass Assembly
     Operator precedence in evaluation of expressions
     Conditional Assembly
     Listing Controls
     Separate Code, Data and EEPROM Segments

Symbol Names
     Symbols up to 32 of the following characters :
          :  @  $  _  A-Z  0-9
     First character must be legal character other than 0-9.
     Special Uses :
          $   Reserved for Debugger Commands
          _   Reserved for Compilers
          @   Temporary Labels
          :   Local Labels
     Case sensitivity is optional.
     Program labels must begin in column 1.
     Non-labels must not begin in column 1.

Numbers
     Default Radix is 10. All numbers must begin 0-9. An alternate radix
     may be selected with one of the following suffixes :
          B   Binary
          O   Octal
          H   Hexadecimal
     Radix suffixes are not case sensitive. All numbers are kept in 32-bit
     two's complement form (-2^31 to 2^31-1).

Strings
     Strings are enclosed by a matching pair of single or double quotes. No
     string operations are allowed.


2. Command Line Options


2.1 Usage

PM can be invoked from the DOS command line using the following command
format :

       
       PM Options filename

Zero or more options can be used to modify the manner in which the
assembler processes the input file. Options begin either with a slash
( '/' ) or a minus ( '-' ). The character following the minus is a letter
which selects the option. Additional characters may be needed by some
options to supply additional information. No spaces may occur within an
option. Options not recognized by the assembler will generate errors and be
ignored.

The first parameter not starting with a minus or a slash is assumed to be
the filename. Extra parameters are ignored.

If PM is invoked with no options and no filename, a brief help screen is
displayed.


2.2. The PM Environment Variable

With programming tools, a programmer will often want certain options to be
invoked consistently. This usually requires the programmer to invoke these
options each time the tools is used. While batch files and makefiles can
reduce this tedium, problems can also occur due to DOS limits on the length
of command lines.

In order to alleviate these problems, the assembler uses a DOS environment
variable named PM. This contains a string of command line options which are
implicitly selected whenever the assembler is invoked. It uses the same
format as the options selected on the command line. Once these have been
processed, then normal command line options are processed and the file is
assembled. Thus, you can use PM to override the assembler defaults and then
use the command line to override PM defaults. This allows a great deal of
customization to the assembler.

For example, suppose you want the PIC Macro Assembler to look more like the
original Parallax assembler. No problem - simply add the following to your
AUTOEXEC.BAT :

     set PM=-EOOBJ

This changes the extension of the output filename from 'HEX' to 'OBJ'.


2.3. Options

Option          Description
C       Identifiers to be Case Sensitive
D       Generates Listing, Symbol Table, and Map File
Ecext   Sets filename extension for specified file type
                L = Listing File
                M = Map File
                O = Output File
                I = Input File
                S = Symbol Table
G#      Set maximum error count
Ipath   Set default INCLUDE/MACLIB directory
Lname   Generate listing (listing filename is optional)
Of      Set output format
                B = Binary
                H = Merged Intel HEX
Q       Force use of explicit extension of source filename

2.3.1. Option -C

By default, all items in PM are case insensitive. Thus, MIXED, Mixed,
mixed, and mIXEd would all be treated as the same label or macro. When the
-C option is invoked, identifiers are case sensitive. In this mode, the
sample identifiers would all be treated as unique. In either mode, opcodes
and pseudo-ops are always case insensitive. This mode is generally intended
for use by compilers where case is important (such as C).

2.3.2 Option -D

PM normally assembles a source file and outputs an executable equivalent of
the program. When the -D option is invoked, a listing, a map and a symbol
table are also generated. This options is mainly used to generate
information for debuggers.

2.3.3. Option -ELext
2.3.4. Option -EMext
2.3.5. Option -EOext
2.3.6. Option -ESext

The names for listing, map, output and symbol table files are generated
automatically by the assembler. These names are created by taking the base
name of the source file (up to 8 characters) and appending an extension
indicating file type. The default extensions are :

File Type       Default Extension
Listing         LST
Map             MAP
Output          HEX or BIN
Symbol Table    SYM

These files are placed in the current directory. The -E options allows
these default extensions to be changed. If the specified default is longer
than 3 characters, it is truncated without warning or error. This option
can be used to make the outputs of PM easier to use with various debugging
platforms.

2.3.7. Option -EIext

Whenever the assembler is invoked, it checks the name of the source file
for an extension. If one is explicitly defined, it is used. If none is
defined, then the assembler appends a default input extension to the
filename. By default, this extension is SRC. The -EI option can be used to
change this default to any three letter combination. If the specified
default is longer than 3 characters, it is truncated without warning or
error.

The -Q option can be used to force the programmer to always specify the
filename extension, if any. Thus, -Q negates the use of the -EI option.

2.3.8. Option -G#

PM can generate an unlimited number of warning. For the sake of clarity,
however, it limits the number of errors that can be generated. By default,
PM terminates with a fatal error if 15 or more errors occur. Using the -G
option, this value may be changed to any arbitrary number.

2.3.9. Option -Ipath

Whenever the assembler encounters an INCLUDE or MACLIB directive, a search
is conducted for the specified file. If a path is explicitly specified,
that directory is searched. If the file is not found, a fatal error is
generated.

If no path is specified, the file is first sought in the current directory.
If not found there, then the system header directory is searched. By
default, this directory is the INC subdirectory of the directory from which
PM is executed. If also not found here, a fatal error is generated.

The -I option can be used to specify the new path of this default
directory. When invoked, the path specified by the -I option is not checked
for validity. Thus, specifying a non-existent or erroneous path can cause
header files to seem to mysteriously disappear (i.e. the assembler can't
find them because the directory doesn't exist).

2.3.10. Option -Lname

When used, the -L option causes the assembler to generate a listing file in
addition to the normal executable image generated. When used by itself, the
listing is placed in a file whose name is created by appending the listing
extension (default is LST) to the base name of the source file. If the -L
options is used to specify a filename, the listing is generated to the
named file.

Note that even if the -D option (which by default generates a listing) is
used, the -L option can still be valuable, because it allows you to specify
the name and path of the listing file.

2.3.11. Option -OB

By default, PM generates Merged Intel HEX format for the executable image.
The -OB option allows the assembler to generate 16-bit binary format.

2.3.12. Option -OH

The -OH option forces PM to generate the executable image in the Merged
Intel HEX format. This option is mainly useful to override the use of the -
OB option that might be specified in the PM environment variable.

2.3.13. Option -Q

Normally, when no extension is explicitly specified for the source, PM
appends a default extension to the filename (SRC by default). The -Q option
prevents this and forces the programmer to explicitly define the extension
(if any) of the source filename.


3. Pseudo-Ops


3.1. CODE
       
       CODE [ Expr ]

The code segment manages the program space of the PIC. The CODE pseudo-op
selects the code segment as the current segment. All bytes generated in the
code segment are placed in the executable image file. The optional
expression may be used to set the load pointer for the code segment.


3.2. DATA
       
       DATA [ Expr ]

The data segment manages the RAM space of the PIC. The DATA pseudo-op
selects the data segment as the current segment. Generation of code or
initialized data in this segment results in an error (due to the Harvard
architecture of the PIC). Thus, DS is the only usable pseudo-op in the data
segment. The optional expression may be used to set the load pointer for
the data segment.


3.3. EEPROM
       
       EEPROM [ Expr ]

The EEPROM segment manages the EEPROM space available in the 8x family of
PICs. The EEPROM pseudo-op selects the EEPROM segment as the current
segment. Generation of code in this segment results in an error (due to the
Harvard architecture of the PIC). Thus, DS, DB and DW are the only usable
pseudo-ops in the EEPROM segment. The optional expression may be used to
set the load pointer for the EEPROM segment.


3.4. ABS
       
       ABS [ Expr ]

Sets the current segment to the absolute segment. This is the default
segment and operates in the mode most familiar to programmers as "absolute"
assembly. All bytes generated in this segment are placed in the executable
image file. The DS command merely advances the load pointer. The optional
expression may be used to set the load pointer for the absolute segment.


3.5. ORG
       
       ORG  Expr

Sets the load pointer for the current space. The user may get the current
value of the load pointer for the current segment via the system variable $.


3.6. DS
       
       DS  Expr

Advances the load pointer by the specified value. DS is normally used to
allocate space within the data or EEPROM segments. When used in the EEPROM
segment, no data is generated in the HEX file for the allocate locations.
This allows EEPROM locations to be allocated that will not be programmed
(assuming your programmer doesn't unconditionally program all EEPROM
locations).


3.7. DB
       
       DB(Expr|String) { , (Expr|String) }

Stores one or more constant bytes in the current segment. In the case of
numeric constants, the resulting values (truncated to 8 bits, if necessary)
are stored. String constants are stored as consecutive bytes.

Since the PIC cannot store data in the code space directly, each byte
generated in the code segment is actually stored as a RETLW instruction.
Bytes generated in the EEPROM segment are stored merely as data. And, of
course, bytes generated to the data segment result in errors.


3.8. DW
       
       DW Expr { , Expr }

Stores the resulting value in the current segment. The value is truncated
to 16-bits. The least significant byte is stored first. Each byte is
generated in the same manner as the DB pseudo-op.


3.9. EQU
3.10. =
       
       Label  EQU  Expr
       Label  =   Expr

Assigns a numeric value to the specified symbol. The two operations are
similar, except it is an error to redefine a symbol created using the EQU
pseudo-op. Symbols created using the = may be reassigned value without
error.


4. Conditional Assembly

Note: PM requires that all symbols be defined at the end of the first pass.
In order to meet this requirement, the evaluation of all conditional
assembly constructs must be consistent in both passes. Thus, unlike other
assembler features, conditional assembly may not assemble correctly if it
relies on forward references.


4.1. IF
4.2. ELSEIF
4.3. ELSE
4.4. ENDIF
       
       IF    Expr
           ...
       ELSEIF Expr
           ...
       ELSE
           ...
       ENDIF

Assembly continues following the first true (i.e. non-zero) expression in
the series of IF and ELSEIF statements and continues until the next
statement in the IF..ELSE..ENDIF chain. If no statement is true and an ELSE
statement is present, the code between ELSE and ENDIF is assembled. The IF
and ENDIF terms are mandatory. One ELSE and multiple ELSEIF terms are
optional.


4.5. IFDEF
4.6. IFNDEF
       
       IFDEF  Label
       IFNDEF Label

The IFDEF and IFNDEF statements may be substituted for the IF term in the
IF..ELSE..ENDIF construct. IFDEF evaluates true if the specified symbol is
defined. IFNDEF evaluates true if the specified symbol is not defined.
There are no IFDEF/IFNDEF replacements for the ELSEIF statement.

The DEF operator may be used for more complicated variations on the
IFDEF/IFNDEF pseudo-ops.


4.7. IFB
4.8. IFNB
       
       IFB  [ Item ]
       IFNB [ Item ]

The IFB and IFNB statements may be substituted for the IF term in the
IF..ELSE..ENDIF construct. IFB evaluates true if an item is listed on the
line following the IFB statement. IFNB evaluates true if no item is listed
on the line following the IFNB statement. There are no IFB/IFNB
replacements for the ELSEIF statement.

Comments are treated as blanks in the evaluation of IFB and IFNB
statements. These constructs are mainly useful in macros to test whether a
parameter has been specified by the caller or has been omitted.


5. Macro Facility


5.1. REPT
       
       REPT Expr
       Body
       ENDM

The body of the macro is repeated the number of times specified by the
numeric expression. The REPT macro is executed immediately.


5.2. IRPC
       
       IRPC Param , String
       Body
       ENDM

The body of the macro is repeated once for each character in the specified
string. The specified parameter is substituted on each expansion with the
scanned character. The IRPC macro is executed immediately.


5.3. IRP
       
       IRP  Param , < Expr { , Expr } >
       Body
       ENDM

The IRP macro is similar to the IRPC macro, except that items from the
specified list (bracketed with < and >) are substituted for the specified
parameter. The IRP macro is executed immediately.


5.4. MACRO
       
        Label   MACRO  Param { , Param }
                Body
                ENDM

Unlike other macro types, MACRO merely creates a template for later macro
expansions. MACRO accepts up to 32 identifiers as parameters. Whenever
found in the body (even in quotes), these parameters are substituted with
the value specified when the macro is invoked. Macros are invoked just as
any other pseudo-op or opcode. Parameters specified in the definition but
not assigned values when invoked are left unsubstituted. This allows macros
with a variable number of parameters if used with the IFB and IFNB
conditional assembly constructs.

Since a macro's name is a label, it must begin in column 1.


5.5. LOCAL
       
       LOCAL  Symbol { , Symbol }

Allows the creation of local symbols in any macro type. A unique temporary
symbol is created for each local symbol for every expansion of the macro's
body. Any number of LOCAL statements may be defined, but they must
immediately follow the macro definition (REPT, IRPC, IRP or MACRO pseudo-
op). Local symbols take the form @@NNNN, where NNNN is a four digit decimal
number assigned sequentially from 0000.


5.6. EXITM

Allows premature abortion of macro expansion. This is useful for
implementing loops whose lengths are not determinant.


5.7. ENDM

All macro definitions are terminated by the ENDM pseudo-op.


6. File Controls


6.1. INCLUDE
       
       INCLUDE String

The INCLUDE statement is replaced with the contents of the specified file.
If no path is specified, the file is searched for first in the current
directory. If not found, then the system header directory is searched. If
still not found, an error results.

By default, the system header directory is the INC subdirectory of the
directory from which PM.EXE is executed. This directory contains files
defining important constants and macros for each of the PICs supported.
This can be changed by the use of the -I command line option.


6.2. MACLIB
       
       MACLIB String

MACLIB is identical in operation to INCLUDE, except that the file is only
parsed on the first pass. This is intended for use on include files that
contain only macro and symbol definitions.

Avoid the use of MACLIB if the file includes any opcodes. If used on such a
file, the file will affect assembly on the first pass, but not on the
second. This can create major discrepancies in the second pass of assembly
and usually results in a large number of confusing error.


7. File and Listing Controls


7.1. TITLE
       
       TITLE  String

Specify the title at the top of every page in listing file.


7.2. PAGE
       
       PAGE   Expr , Expr
       PAGE   Expr
       PAGE

If the first parameter is defined, it sets the page width for the listing.
The page width must be between 80 and 255 characters (default is 132).
Characters beyond this width are truncated from the listing. If the second
parameter is defined, it sets the page length of the listing (default is
60). If the page length is set 0, no automatic page breaks are generated.

If the PAGE pseudo-op is used without parameters, if forces a page break in
the listing.


7.3. LIST
7.4. NLIST

If the -L option is used, the listing counter is initialized to 1.
Otherwise, it defaults to an initial value of 0. LIST increments the
listing counter. NLIST decrements the listing enable counter. Whenever the
listing counter is positive, lines are generated for the listing.

This simple arrangement allows a greater flexibility in listing control
than did earlier versions of PM. For example, the source file may contain
listing controls without unconditionally generating a listing.


7.5. MTLIST
7.6. NMTLIST

If the MTLIST pseudo-op is used, enough lines are generated to display all
bytes generated by the listed statement. This is the default.

If the NMTLIST is pseudo-op is used, only one line is listed for each line
of source code. If a line generates more than 4 words of code, additional
bytes are not displayed and the line is marked with an '#'.


7.7. CLIST
7.8. NCLIST

The NCLIST pseudo-op forces all portions of IF..ELSE..ENDIF constructs to
be listed. This is the default.

The NCLIST pseudo-op forces only those portions of IF..ELSE..ENDIF
constructs that are assembled to be listed. The conditional statements
themselves are always listed, although nested IF..ELSE..ENDIF constructs in
unassembled blocks of code are not listed.


7.9. LALL
7.10. XALL
7.11. SALL

If LALL pseudo-op is used, all lines of a macro expansion are listed. This
is the default.

If XALL pseudo-op is used, only those lines of a macro expansion which
generate code are listed.

If SALL pseudo-op is used, no lines of a macro expansion are listed.


8. Device Controls

PM was written to be compatible with all 12-bit and 14-bit PICs. The
assembler was designed to handle the architectural limits of both core
types. Each program must specify which core and a specific set of
capabilities by using the DEVICE statement.


8.1. DEVICE
       
       DEVICE Expr { , Expr }

The DEVICE pseudo-op takes one or more comma separated 32-bit expressions
as parameters. The bits 31 and 30 of each value distinguishes one of four
separate processor specifications. These two bits determine how the
remaining thirty bits of that value are interpreted.

8.1.1. Fuse Specifier

00 AAAAAAAAAAAAAA XX 00000000000000
        AND Bits        OR Bits

If the upper two bits of a parameter are 00, this word defines the
configuration fuses. PM allows arbitrary control of a 14-bit fuse word.
When a fuse specifier is used, two actions are taken:

  The current fuse value is ANDed with the upper 16-bits of the 32-bit
  word.
  The resulting fuse value is then ORed with the lower 16-bits of the
  32-bit word.

XX is unused.

This system allows one or more values to be chained together to control
various bit locations in the fuses. These may occur in any order or even in
multiple DEVICE statements. The actual values used to set the fuses are
normally defined in the header file defined for a particular component or
family of components. Below is a partial table containing the most common
fuse specifiers. For a full list, consult the device header for your
particular device.

DEVICE Parameter        Description
RC_OSC                  RC Oscillator
HS_OSC                  HS Oscillator
XT_OSC                  XT Oscillator
LP_OSC                  LP Oscillator
BOD_ON                  Brown-Out Detection Enabled
BOD_OFF                 Brown-Out Detection Disabled
PROTECT_ON              Code Protection Enabled
PROTECT_OFF             Code Protection Disabled
WDT_ON                  Watch Dog Timer Enabled
WDT_OFF                 Watch Dog Timer Disabled

8.1.2. Core Specifier

01CCXXXXRRRREEEEEEEEPPPPPPPP

01 - Proc Specific Flag
CC - Core Type (0 = 12-Bit, 1 = 14-Bit)
XXXX - Unused
RRRR - ROM (512 Byte Pages)
EEEEEEEE - EEPROM (Bytes)
PPPPPPPP - Processor Code

The core specifier defines the processor's core type (12-bit or 14-bit) and
the amount of ROM/EEPROM available. This information is needed to generate
core-appropriate instructions and to perform range checking on addresses.

Additionally, an arbitrary 8-bit numeric code may be assigned to the
processor. While PM doesn't use this information, it is embedded in the
output file and this information is used by some simulators, programmers,
and other third party development tools. There is no standardization (among
tool providers) on these numbers.

No attempt is made to provide RAM availability information. The asymmetry
of data pages makes it difficult to perform error checking without
generating warnings on valid instructions.

Unlike fuse specifiers, a core specifier must be set in one value - it
lacks the running accumulation effect of fuse specifiers.

8.1.3. Reserved Options

The two remaining DEVICE fields (10 and 11) are reserved for future use.
Any DEVICE value containing these upper 2 bits will generate an error.


8.2. ID
       
       ID  Expr
       ID  String
       ID  CHECKSUM

Each PIC has a 16-bit (12-bit core) or 28-bit (14-bit core) ID. This value
can be set in one of three methods. A numeric expression or string constant
can be used for either core type. For 12-bit cores only, the reserved word
CHECKSUM may be used. This forces the Parallax PIC Programmer to compute
the checksum of the PIC code space.


8.3. RESET
       
       RESET  Expr

Each time a PIC is powered up or reset, the PC is set to a determinant
spot. It is assumed that the programmer will use this knowledge to get his
program to start executing whenever the PIC is ready. The most common
method of doing this is to place a GOTO instruction at this spot. In the
12-bit core, execution begins with the last word of ROM. In the 14-bit
core, execution begins at 0000h.

The RESET pseudo-op places a GOTO at the correct address determined for the
current processor type (as set by the DEVICE pseudo-op). The RESET command
is most commonly used in programs for 12-bit cores.


9. Expressions


9.1. Calculations

Even though PIC processors only handles 8-bit math and use 11-bit or 13-bit
addresses, PM performs all calculations and stores all constants 32-bit,
two's complement form.

No string operations are available.


9.2. Operators

Operator      Function      Unary  Precedence
  ( )    Grouping Operators  x       1
  REF     Label Reference    x       2
  DEF      Label Defined     x       2
   -        Unary Minus      x       2
   +         Unary Plus      x       2
   ~        Bitwise NOT      x       2
   !        Logical NOT      x       2
   HI       MSB of Word      x       2
   LO       LSB of Word      x       2
   *          Multiply               3
   /           Divide                3
   %          Modulus                3
   >>       Shift Right              4
   <<        Shift Left              4
   -          Subtract               5
   +          Addition               5
   =        Equivalence              6
   <>        Inequality              6
   <         Less Than               6
   >        Greater Than             6
   <=    Less Than or Equal          6
   >=   Greater Than or Equal        6
   &        Bitwise AND              7
   ^        Bitwise XOR              8
   |         Bitwise OR              8
   .     Bit Address Operator        9

Expressions are resolved from left to right using operator precedence to
resolve ambiguities in evaluation. The precedence of each operator is
shown. Operators with the highest precedence (i.e. those which are
evaluated first) are show as precedence 1.

9.2.1. Bit Extension

Whenever bits in a number are inverted, this inversion occurs in all 32
bits. This causes the bit-wise inversion and negation of byte-sized numbers
with 1's in the upper bits. This, however, isn't usually a problem, since
opcodes usually truncate calculated values to the appropriate size without
generating warnings or errors.

9.2.2. Modulus

Modulus is the proper name for what you may have learned in school as the
"remainder". In short, it is value that is "left over" when one integer
value is divided by another. In systems which support signed numbers, there
is some ambiguity as to the sign of the remainder for negative numbers. PM
returns a modulus with the same sign as the dividend.

9.2.3. Shift Right

Shift right is often used as a fast-divide for binary values (e.g. shifting
right by 3 bits is the same as dividing by 8). Since PM works with signed
numbers, a number shifted right will retain the value of the 32nd bit (i.e.
sign extension).

9.2.4. DEF & REF
       
       DEF ( LabelList )
       REF ( LabelList )

In order to allow PM to simulate a linking library, the DEF and REF
operators are defined. The DEF operator returns true (1) if the specified
label(s) have been defined earlier in the program. Similarly, the REF
operator returns true (1) if the specified label(s) have been used
(referenced) earlier in the program. Both return 0 if the tested condition
is false.

To increase flexibility, more than one label may be tested. In fact,
logical operators ('|' for OR and '&' for AND) and parenthesizes have are
supported for complex label lists.


9.3. Numeric Constants

All numbers default to radix 10. All numbers (regardless of radix) must
begin with digits 0-9. Other bases may be selected by appending the
following suffixes. Suffixes are not case sensitive.

B       Binary
O       Octal
H       Hexadecimal


9.4. String Constants

PM supports string constants mainly for the purpose of generating strings
of RETLWs (via the RETW opcode and DB pseudo-op). Strings may be enclosed
by either single ( ' ) or double ( " ) quotes. If single quotes are used,
then double quotes may be used freely within the string, and vice versa.
Single quotes may not appear within a single quoted string and double
quotes may not appear within a double quoted string.

String constants may also be used to drive the IRPC macro pseudo-op. On
each expansion of the IRPC macro, the replacement parameter is replaced
with an unquoted character. When used as a parameter for macros defined
using the MACRO pseudo-op, the quoted string is passed unmodified (quotes
intact).


9.5. List Quoting

The IRP macro is driven by a list of comma separated items bracketed with <
and > characters. This item can be so useful, that < and > have been given
a special "quoting" function in macros. When the < character is encountered
in the parameter list for a macro defined using the MACRO pseudo-op, the
parameter is considered to contain all characters up to the next >. This
type of bracketing may not be nested. When this parameter is substituted,
the < and > are stripped from the substitution.

 1                defb1  macro  list
 2                       irp    item,<list>
 3                       db     item
 4                       endm
 5                       endm
 6
 7                defb2  macro  list
 8                       db     list
 9                       endm
10
11                       defb1  <1,"One",2,"Two">
 +                       irp    item,<1,"One",2,"Two">
 +                       db     item
 +                       endm
 + 000- 801              db     1
 + 001- 84F 86E 865      db     "One"
 + 004- 802              db     2
 + 005- 854 877 86F      db     "Two"
12                       defb2  <1,"One",2,"Two">
 + 008- 801 84F 86E 865  db     1,"One",2,"Two"
   00C- 802 854 877 86F


9.6. Identifiers

Identifiers are the names used as program labels, variables and macro
names. Although they can be any length, only the first 32 characters are
significant and they must be unique in these 32 characters. Identifiers
differing only in the 33rd or later character are considered identical.
Identifiers consist of any of the following characters :

                         A-Z  0-9  : @ $ _

Identifiers may begin with any of these characters except 0-9. The first
character may have a special meaning, as described in the following
sections.

9.6.1. Identifiers Starting with ':'

Symbols starting with a colon ( ':' ) are local symbols. This method
appends this local label to the last non-local label (i.e. label beginning
with other than a colon). This allows simple labels within a global block
not to pollute valuable name space. The labels can be referenced within
this local block using the abbreviated local name. To reference this label
outside the block, the full form needs to be used (i.e. non-local:local).

9.6.2. Identifiers Starting with '$'

Symbols starting with the dollar sign ( '$' ) are reserved for future
debugging use. Currently, only one symbol starting with the dollar sign is
reserved by the assembler, which is the dollar sign itself. It is used to
get the value of the load pointer for the current segment.
     
9.6.3. Identifiers Starting with '_'

Symbols starting with the underscore ( '_' ) are reserved for use by
compilers.

9.6.4. Identifiers Starting with '@'

Symbols starting with the at symbol ( '@' ) are treated as temporary
labels. Temporary symbols are treated just like other labels, except they
are not included in the symbol table. The LOCAL pseudo-op generates symbols
in the form of @@NNNN, where NNNN is a four digit decimal number starting
with 0000.


9.7. System Variables

In order to make programming easier, PM defines some system variables. You
cannot redefine these variables, although they can be used as you would
other variable.

9.7.1. $

The dollars sign ( $ ) is used to get the value of the load pointer for the
current segment. Each of the four segments (CODE, DATA, EEPROM and ABS) has
its own load pointer. Therefore, the value of $ depends on the segment in
which it appears.
     
9.7.2. DEVICE

DEVICE returns the core specifier. For details on these flags, see the
description of the DEVICE pseudo-op.


10. File Formats


10.1. Source File

; Test File for PIC Macro Assembler

        include 'T13.INC'       ; Show Include File

SIZE    equ     10h             ; Show Assignment Statement
        mac     "uChip"         ; Show Macro Expansion

        nmtlist                 ; Suppress Multi Line Listing
        db      "uChip"         ; Generate Constants
        mac     "uChip"         ; Expand & Generate Constants

PM uses a common collimated format for the input (or source) file. This is
the same format as used by the original Parallax PIC assembler. Items
starting in column 1 are either labels, variables, or macro names. Items
beginning in column 2 or later are assumed to be opcodes or pseudo-ops.
Depending on the opcode or pseudo-op, zero or more comma separated
parameters may follow the opcode/pseudo-op. Comments (which begin with a
semicolon) may begin in any column.


10.2. Map File

The MAP file is used to link the executable file to the source file. The
MAP file contains one 16-bit number (2 bytes) for each word in the code
space of the target processor. This 16-bit number (stored LSB first) is the
number of the line in the source file which generated the corresponding
instruction in the executable image. No provisions are made for mapping
instructions on to lines in generated in INCLUDE or MACLIB files.


10.3. Binary Output File

The simplest output format of PM is the 16-bit binary format. The binary
file contains one 16-bit word (2 bytes) for each word in the code space of
the target processor. This word (stored LSB first) contains the actual PIC
opcode for the corresponding address (i.e. the first word of the file
corresponds to address 000h in the target processor). The most significant
bits of the word which are unused by the processor (4 in the 12-bit core, 2
in the 14-bit core) are zeroed. Addresses not assigned values by the
assembler are stored with all 1's (0FFFh in the 12-bit core, 3FFFh in the
14-bit core).


10.4. Merged Intel HEX File

The default output format of PM is the Merged Intel HEX format. This
section will not describe the standard Intel HEX format (which is well
documented elsewhere), but details the deviations from the standard for the
Merged format.

Each word of the executable image is stored in consecutive bytes in the
Intel format (LSB first). To adjust for the 2-byte word size of the PIC,
the Intel HEX addresses are doubled (since the format is strictly byte
oriented). With these two adjustments made, the Merged Intel HEX format is
identical to the standard Intel HEX format.

Unlike the binary format, only bytes which are actually generated have any
value specified in the Merged Intel HEX format. If some fill value is
required, this must be handled by your PIC programmer.

Unlike the binary file format, the Merged Intel HEX format also contains
information on the processor type, ID/checksuming flag and the fuses.

10.4.1. PIC16C5x Device Descriptor
     
:061FFA00 0001 FFFF 03 02 DD                                     

The device descriptor for the PIC16C5x family is shown above. The checksum
flag (2 bytes) is 0000 if no checksum is to be calculated and 0001 is the
checksum is to be calculated. The ID field contains the 16-bit ID (LSB
first) as specified by the ID pseudo-op. The ID is FFFF if the checksum for
the PIC is to be calculated (i.e. Checksum = 0001). The processor numbers
for the PIC16C5x family are as follows :

00      PIC16C54
01      PIC16C55
02      PIC16C56
03      PIC16C57
04      PIC16C58

For details on the fuses field, see the description of the DEVICE
pseudo-op.


10.4.2. PIC16Cxx Device Descriptor
     
:084000007F007F007F007F00BC - Sets ID starting at location 2000h

:04400E00FF3F000070 - Sets Fuses at location 2007h

 
10.5. Symbol Table File

   a_abs                 0000000A
   a_code        CODE    0000000A
   a_data        DATA    0000000A
   a_eeprom      EEPROM  0000000A
   x_abs                 00000000
   x_code        CODE    00000000
   x_data        DATA    00000000
   x_eeprom      EEPROM  00000000

The symbol table contains all labels (except labels starting with the '@'
character) defined in the program. This file contains three unlabeled
columns. The first column contains the actual name of the symbol. The case
of the defining instance is preserved and only the first 32 significant
characters are displayed. The second column may contain the label's type
(CODE, DATA or EEPROM). This is determined by the segment in which the
label was defined. No type is generated for the ABS segment, which is the
default. Finally, the last column contains the full 32-bit representation
of the number in hexadecimal. Note that base-16 is understood and no 'H'
suffixes or '0x' prefix has been included. Symbols are listed in
alphabetical order.

This format is intended for use by debuggers and is not really made human
readable. While the items currently begin in fixed column, this may change
in the future. Those parsing these items should rely on the use of
whitespace as separators, rather than column numbers. Additional fields
(columns) may be added to the end of each line in the future, so those
processing this format should ignore items occurring after the value.


10.6. Listing File

 1                ; Test File for PIC Macro Assembler
 2
 3                              include 'T13.INC'
*1                      mac     macro   p
*2                              db      'p'
*3                              endm
*4                              mac   "uChip"
 + 000- 822 875 843 868         db    '"uChip"'
   004- 869 870 822
 4
 5 =0010                SIZE    equ   10h
 6                              mac   "uChip"
 + 007- 822 875 843 868         db    '"uChip"'
   00B- 869 870 822
 7
 8                              nmtlist
#9 00E- 875 843 868 869         db    "uChip"
10                              mac   "uChip"
#+ 013- 822 875 843 868         db    '"uChip"'

The listing file gives the programmer the most information about the actual
assembly of the source file, and is therefore the most complex. This file
contains three columns of assembly information followed by the source code.

The first column of the listing is a single character which gives
additional information about the line being listed. The following table
shows these tag characters. While multiple tags might apply to a single
line, only one is listed. Thus, they are listed below in order of
preference :

#   More than 4 Words Generated, but Suppressed
*   Line is from Include File
    Normal Source Line

The second column displays the line number. If the current line is from an
included file, the number of that line within the include file is listed.
If the current line is generated by a macro expansion, the line number is
replaced with a '+'.

The last column displays the results of the line. If the line computes a
value for a label or as the parameter for a pseudo-op, then the value is
display either as a 4 or 8 hexadecimal digit number following an '='. If
the line generates code, the current load pointer is displayed, followed by
'-' and one or more lines of up to 4 words per line. For comments and many
pseudo-ops, this column is left blank.


11. Assembling Existing Parallax Code

For the most part, PM will assemble existing Parallax code (previously
assembled w/ PASM, PASM71 or PASMX) with little or no change. The following
steps may be needed :

  Depending on the type of PIC, place the following line in the source
  prior to any lines of code :

  PIC12C50x     MACLIB  'P12C50x.INC'
  PIC16C5x      MACLIB  'P5x.INC'
  PIC16C61      MACLIB  'P61.INC'
  PIC16C62      MACLIB  'P62.INC'
  PIC16C62A     MACLIB  'P62A.INC'
  PIC16C62x     MACLIB  'P62x.INC'
  PIC16C63      MACLIB  'P63.INC'
  PIC16C64      MACLIB  'P64.INC'
  PIC16C64A     MACLIB  'P64A.INC'
  PIC16C65      MACLIB  'P65.INC'
  PIC16C65A     MACLIB  'P65A.INC'
  PIC16C71      MACLIB  'P71.INC'
  PIC16C71x     MACLIB  'P71x.INC'
  PIC16C72      MACLIB  'P72.INC'
  PIC16C73      MACLIB  'P73.INC'
  PIC16C73A     MACLIB  'P73A.INC'
  PIC16C74      MACLIB  'P74.INC'
  PIC16C74A     MACLIB  'P74A.INC'
  PIC16C84      MACLIB  'P84.INC'
  PIC16F8x      MACLIB  'PF84x.INC'

  If you receive the error [225] Undefined Symbol 'W', the source may
  contain the Parallax opcode MOV W,fr-W. This opcode is not supported by
  PM. This opcode can, however, be replaced with the Microchip equivalent
  SUBWF fr,0.

             Becomes
   MOV W,fr-W     SUBWF fr,0

  The SUBB instruction of PASM was specialized for use with the PIC carry
  flag (C), which is inverted from carry flags in most conventional
  processors (0 if a borrow occurs). Thus, SUBB modified there
  destinations if the specified bit is 0, which is nonsense for general
  bit usage (although it makes sense for 16-bit subtraction). If you used
  these instructions in your program, you must invert the sense of the
  bit.

             Becomes
   SUBB fr,bit    SUBB fr,/bit
   SUBB fr,/bit   SUBB fr,bit

  The original Parallax assembler evaluates equations strictly left to
  right (i.e. 3+4*5 = 35). PM also evaluates equations left to right, but
  uses operator precedence (i.e. 3+4*5 = 23). This typically creates no
  problems since PIC programs tend to be relatively simple. You should,
  however, check for complex calculations to assure that their evaluation
  will be correct.


12. Warnings

100  Attempt to Skip MultiByte OpCode @ Address

Indicates the current instruction is a multibyte Parallax instructions and
that the previous instruction is attempting to skip it. Obviously, if this
were done unintentionally, a successful skip would enter the current opcode
mid-instruction.

101  Use of Local Label Prior to Use of Non-Local Label

Indicates that a local label (i.e. starting with a colon) has been defined
prior to the definition of a non-local label (i.e. a legal label name
starting with other than a colon). Because local names depend on the named
of last non-local label defined, this usage is obviously suspicious. The
label generating the warning is not expanded as are other local labels (see
Local Labels).

102  Code Crosses Boundary @ Address

Both the 12-bit and 14-bit PIC cores have paged architectures in which the
normal incrementing of the PC doesn't extended into page select registers
(PA0 & PA1 in the PIC16C5x, PCLATH in the PIC16Cxx). If a continuous block
of code is generated across a page boundary and a forward jump is coded,
the actual jump location will be to the previous page.

104  Called Addresses must Reside in Lower Half of Page

In the PIC16C5x family, the 9th bit of address is zeroed on calls. Thus,
call destinations must reside in the lower 256 words of any 512 word page.
This mistake is only a warning since calls made to the upper 256 words will
alias to an address in the lower 256 words of the page.

105  Bit Addresses are the Same

This warning indicates that you have attempted to copy a bit to itself. The
Parallax MOVB bit,bit instruction will correctly copy a bit to itself,
although the operation has no useful applications.

106  Register Addresses are the Same

This warning indicates that you have attempted to copy a register to
itself. While this is legal, it generates a MOVF and MOVWF instruction,
placing the moved value in W and setting the Z flag. If your intentions are
to set the Z flag according to contents of the specified register, the TEST
instruction will do this in one word and without destroying the contents of
W.


13. Errors

Unless specified otherwise, each of the following errors will terminate the
assembly of the current line. If possible, the assembler will generate
correct code (or at least the correct number of words) before the line is
aborted. Assembly continues with the next line of source.

Unless otherwise specified, the error report has no side effects other than
to bump the error count.

200  Instruction Restricted to 14-Bit Core

The opcode of the specified line cannot be used for the PIC16C5x family:
          ADDLW  #literal
          SUBLW  #literal
          RETFIE
          RETURN

201  'Character' Expected

The assembler expected, but didn't find, the specified character.

202  Illegal Character 'Character'

The assembler doesn't recognize the legal use of the specified character.

203  '--' or '++' Expected

The Parallax instruction MOVSZ (MOVe and Skip in Zero) must take one of two
forms :   MOVSZ  W,++fr
          MOVSZ  W,--fr

204  'W' Expected as First Parameter

The Parallax instruction MOVSZ (MOVe and Skip in Zero) must take one of two
forms :   MOVSZ  W,++fr
          MOVSZ  W,--fr

205  Illegal Use of Keyword 'Keyword'

Indicates that the specified identifier is a reserved word of the assembler
and has been improperly used.

206  CHECKSUM Not Supported in 14-Bit Core

The CHECKSUM option may be used as the ID of a processor in the PIC16C5x
family. This option is not legal on the 14-bit core.

208  Illegal Use of SUB Instruction

This error indicates an attempt was made to use the illegal instruction :
         SUB  W,fr

209  Indirect Jump Expected in Form of 'PC+W'

This error indicates an attempt was made to use the illegal instruction :
         JMP  PC+Expr

210  Bit Addresses Must Differ

The Parallax MOVB bit1,/bit2 instruction requires that the source and
destination bits be different. An attempt to copy the complement of a bit
to itself will result in the unconditional setting of the bit.

211  Poorly Formed Numeric Constant 'Token'

Indicates that the symbol is not a legally formed numeric token. If any
initial portion of this token is a valid constant, that portion is
converted and its value is used as the result of the token.

212  Extra Tokens on End of Line

Some initial portion of the current line assembled correctly, but
additional assembly tokens remain unprocessed. This is often the result of
a syntax error (extra parameters, misplaced or missing punctuation, etc.).
Code is generated for the correct initial portion of the line.

213  IRPC Expected Id or String Constant

The second parameter of the IRPC macro definition is the item (scanned
character by character) which drives the macro expansion. This item must be
either an identifier or a quote-enclosed string constant.

214  IRPC Missing Replacement Parameter

The first parameter of the IRPC macro definition is the variable which
accepts the characters scanned from the second parameter. The first
parameter must be an identifier unique within the definition of the macro.

215  Attempt to Redefine Macro 'Identifier'

An attempt was made to redefine the named macro.

216  Attempt to Redefine Macro Parameter 'Identifier'

Each parameter and local variable of a macro must be unique. This error
indicates that a parameter or local name has been duplicated.

217  Attempt to Generate Code in Non-Code Segment

Due to the Harvard Architecture (split code and data spaces) of the PICs,
instructions may only be executed from CODE space (ROM). This error
indicates that an attempt was made to generate opcodes in the data or
EEPROM segments. In general, only the DS pseudo-op is legal in the data
segment and DS, DB and DW are the only legal pseudo-ops in the EEPROM
segment.

218  Address Limit of Address Exceeded

This error indicates that current segment has overflowed.

219  Collision in HEX File @ Address

This error indicates that more than one word has been generated for the
specified ROM address.

220  Illegal Bit Number

In the PIC (and most processors), the bits of a byte are numbered from 0
(the least significant bit - LSB) to 7 (the most significant bit - MSB).
This error indicates that the specified bit number is not in the range of 0
to 7.

221  Illegal Bit Address

The four basic bit operators of the PIC take either an 8-bit field (12-bit
core) or a 10-bit field (14-bit core). This is composed of a register
address and a bit number. If this combination exceeds the 8 or 10 bit range
for the selected processor, this error is generated. Note that only the
composite value is checked - this check in no way guarantees the validity
of the bit number or the register address. These value are, however,
checked whenever they can be checked as separate parameters.

222  Illegal Destination Specifier

Many Microchip instructions expect the second parameter to specify the
destination of the operation result : 0 if the result is also the source
register, 1 if the result is to be placed in W. This error indicates that a
numeric expression was used for this parameter which neither evaluated to 0
nor 1. For clarity, the second parameter can be omitted to use the source
register as the destination and W can be used to specify W as the
destination.

223  Illegal TriState File Register Address Register

The TRIS instruction may only operate upon registers 5, 6, or 7. This error
indicates that the specified register value was other than 5, 6, or 7. The
equivalent Parallax instruction may also generate this error :
        MOV !Register,Source

224  Keyword Directive Only for Use in Macros

Some keywords (such as LOCAL and ENDM) only have meaning in the definition
of a macro body. This error indicates that an attempt was made to use such
a keyword in some other context.

225  Undefined Symbol 'Identifier'

A reference was made to the specified symbol although no such symbol was
detected in the first pass of the assembler.

226  Numeric Constant or Symbol Name Expected

A legal expression is a well formed sentence containing operators and
terminals from which values for the operators are derived. This error
indicates that an expression terminal was encountered which didn't evaluate
to a numeric value.

227  Divide by Zero

An attempt was made (in the source) to divide by zero at assembly time.

228  Modulus by Zero

An attempt was made (in the source) to take the modulus of a number by zero
at assembly time.

229  Device Doesn't Support EEPROM

An attempt was made to generate values in the EEPROM segment for a device
which doesn't support EEPROM.

230  Collision  in EEPROM @ Address

An attempt was made to generate more that one value for the specified
EEPROM location.

231  Attempt to Redefine 'Identifier'

An attempt was made to assign a new value to a symbol defined either as a
program label or using the EQU pseudo-op. A common (but confusing) source
of this error can result from different flows through conditional assembly
blocks between the first and second passes. While this type of variant
programming can be done, it is very tricky and poor programming practice -
it should be avoided.

232  File Name Expected

Indicates that the parameter specified for the current INCLUDE or MACLIB
pseudo-op is not a quoted string.

233  String Expression Expected for Title

The TITLE pseudo-op is used to replace the normal copyright notice of the
listing with a customized header. This new header must be specified as a
quoted string and is the only parameter of the TITLE pseudo-op.

234  Identifier Expected

The IFDEF and IFNDEF conditional assembly pseudo-ops require one identifier
as it parameter. This error is generated whenever this parameter is other
than a legal identifier.

235  Opcode Expected Instead of 'Token'

Any text starting in column 2 or later which is not a commented is assumed
to either be an opcode, a pseudo-op or the name of a defined macro. All
other tokens will generate this error.

236  Label 'Identifier' Undefined in Pass 0

This error indicates that an attempt was made to define the specified
symbol in pass 1, although no definition was made for the symbol during
pass 0. This is almost always the result of different flows through
conditional assembly blocks between pass 0 and pass 1.

237  IRP Missing Replacement Parameter

The IRP macro takes two parameters. The first parameter is an identifier
which is substituted on each expansion with the next item from the comma
separated list (the second parameter). This error indicates that the
identifier expected for the first parameter of the IRP statement was not
found.


14. Fatal Errors

300  Too Many Errors

The assembler can generated an unlimited number of warnings, but the number
of errors is limited. While this value defaults to 15, it can be changed
using the -G option. This fatal error is generated when this allowance is
exceeded.

301  Out of Memory

Indicates that the symbol table, macro table and other memory requirements
for internal bookkeeping have exceeded the memory capacity of your PC.
While this error message is unlikely, it can occur on limited or heavily
burdened systems. If not already at the 640K limit for conventional memory,
add memory. Unloading or loading high of TSRs and network drivers can
increase usable memory. Memory may also be gained by reducing the number of
BUFFERS and FILES allocated in CONFIG.SYS.

302  Unable to Open File 'Filename'

Indicates that DOS was unable to open the specified file. This is either
because the file could not be found or not enough file handles were
available (this usually only occurs with deep nesting of INCLUDE and MACLIB
statements). If the file exists, make sure it resides in the current
directory. If the file is an INCLUDE or MACLIB file, also check in the
default include directory. While this defaults to the INC subdirectory of
the directory where PM.EXE is kept, it can be modified using the -I option.
If the file is found as described above, try increasing the number of FILES
in CONFIG.SYS.

303  Unable to Create File 'Filename'

Indicates that DOS was unable to create the specified file. This is either
because there are not enough file handles available or there is not enough
space on the destination disk. If there is adequate disk space available,
try increasing the number of FILES in CONFIG.SYS.

304  No Source File Specified

This error is generated if PM is invoked with options, but without the name
of a source file. If PM is invoked with no options and no source name, a
brief help screen is displayed.

305  Unable to Write to File 'Filename'

Indicates that DOS was unable to write to the specified file. This usually
results when there is not enough space on the destination disk or the
specified file has some special write protection (such as DOS SHARE.EXE).

306  Page Width must be 80 to 255 Columns

The PAGE pseudo-op is used to specify the size of the listing page. The
first parameter is used to specify the width of the page. This value must
be between 80 and 255, inclusive.

307  Illegal Device Type

An attempt was made to use an illegal specifier with the DEVICE statement.
Such values would have 10 or 11 as the two most significant bits.

308  Macro Buffer Overflow

An attempt was made to define a macro which was larger than 4K. This
usually indicates a missing ENDM pseudo-op.


15. Internal Errors

These errors are not documented, because they should not occur. If they
occur, technical support should be contacted and a copy of the code
producing the error should be made available.

400  Attempt to Free Non-Allocated Memory [Pointer]
401  Attempt to Reference Non-Allocated Memory [Pointer]
402  Attempt to Pop Empty Symbol Table Stack
403  Attempt to Exit on Empty File Stack
404  Attempt to Pop Empty Macro Stack
405  Macro Stack Error
406  Attempt to Pop Empty Conditional Assembly Stack
407  No Function Handler for 'Keyword'


16. Microchip Instruction Set

The PIC Macro Assembler can use the 8051 style mnemonics created by Parallax
or the Microchip mnemonics.  The included header files which define the
register and bit names, however, are in the Parallax form.  This format
includes the register name and bit name into one symbol.  This makes it
quicker and easier to write the code but also makes it somewhat incompatible
with Microchip code that may be scattered throughout their data books.

It is a fairly simple matter to convert these symbols as they are typed in
or use your text editor's or word processor's search and replace function to
change them.

For example, if the Microchip code says:

        bsf     status,rp0      ;set bit rp0

the equivalent PM code would be:

        bsf     rp0             ;set bit rp0

The reason behind this change is that the symbol "rp0" is defined to already
include the information that it is in the status register.  See the PM
include files, P8X.INC for example, for a complete list of these symbol
definitions for each PIC.


16.1. Summary of Microchip Instructions

ADDLW   k
ADDWF   f,d
ANDLW   k
ANDWF   f,d
BCF     f,b
BSF     f,b
BTFSC   f,b
BTFSS   f,b
CALL    k
CLRF    f
CLRW
CLRWDT
COMF    f,d
DECF    f,d
DECFSZ  f,d
GOTO    k
INCF    f,d
INCFSZ  f,d
IORLW   k
IORWF   f,d
MOVF    f,d
MOVLW   k
MOVWF   f
NOP
RETFIE
RETLW   k
RETURN
RLF     f,d
RRF     f,d
SLEEP
SUBLW   k
SUBWF   f,d
SWAPF   f,d
XORLW   k
XORWF   f,d


17. Parallax Instruction Set

Early adopters of the PIC microcontroller were less than pleased with the
PIC's instruction set. While appropriate for a RISC architecture, it is
somewhat cryptic and makes code unreadable. Parallax realized this when
they decided to build PIC development tools. To overcome the problem,
Parallax decided to build an 8051-like instruction set on top of the PIC
instruction set.

The Parallax instruction set has some advantages. Most notably, the
instructions are more intuitive and generally allow programmers to write
more readable code. It also has some disadvantages. First, each Parallax
instructions expands to between 1 and 4 PIC instructions. This variable
instruction & execution length makes "cycle counting" difficult. Second, it
is not always obvious from the Parallax instruction what is actually
happening. Consider the instruction mov fr,#lit. While the instruction does
the obvious (setting the file register to the literal value), it also has a
less obvious side effect (setting the W register to the literal value).
Such hidden side effects can make debugging difficult.

Recognizing that each instruction set has advantages and disadvantages, PM
supports both. While the PIC instructions set is widely documented, the
Parallax instruction set is not. That is the purpose of this supplement.
                      

17.1. Summary of Parallax Instructions

ADD     fr,#lit
ADD     fr1,fr2
ADD     fr,W
ADD     W,#lit *
ADD     W,fr
ADDB    fr,bit
AND     fr,#lit
AND     fr1,fr2
AND     fr,W
AND     W,#lit
AND     W,fr
CALL    addr
CJA     fr,#lit,addr
CJA     fr1,fr2,addr
CJAE    fr,#lit,addr
CJAE    fr1,fr2,addr
CJB     fr,#lit,addr
CJB     fr1,fr2,addr
CJBE    fr,#lit,addr
CJBE    fr1,fr2,addr
CJE     fr,#lit,addr
CJE     fr1,fr2,addr
CJNE    fr,#lit,addr
CJNE    fr1,fr2,addr
CLC
CLR     fr
CLR     W
CLR     WDT
CLRB    bit
CLZ
CSA     fr,#lit
CSA     fr1,fr2
CSAE    fr,#lit
CSAE    fr1,fr2
CSB     fr,#lit
CSB     fr1,fr2
CSBE    fr,#lit
CSBE    fr1,fr2
CSE     fr,#lit
CSE     fr1,fr2
CSNE    fr,#lit
CSNE    fr1,fr2
DEC     fr
DECSZ   fr
DJNZ    fr,addr
IJNZ    fr,addr
INC     fr
INCSZ   fr
JB      bit,addr
JC      addr
JMP     addr
JMP     PC+W
JMP     W
JNB     bit,addr
JNC     addr
JNZ     addr
JZ      addr
LCALL   addr
LJMP    addr
LSET    addr
MOV     fr,#lit
MOV     fr1,fr2
MOV     fr,W
MOV     OPTION,#lit
MOV     OPTION,fr
MOV     OPTION,W
MOV     !fr,#lit
MOV     !fr1,fr2
MOV     !fr,W
MOV     W,#lit
MOV     W,fr
MOV     W,/fr
MOV     W,fr-W **
MOV     W,++fr
MOV     W,--fr
MOV     W,<<fr
MOV     W,>>fr
MOV     W,<>fr
MOVB    bit1,bit2
MOVB    bit1,/bit2
MOVSZ   W,++fr
MOVSZ   W,--fr
NEG     fr
NOP
NOT     fr
NOT     W
OR      fr,#lit
OR      fr1,fr2
OR      fr,W
OR      W,#lit
OR      W,fr
RET
RETI
RETW    lit,lit,...
RL      fr
RR      fr
SB      bit
SC
SETB    bit
SKIP
SLEEP
SNB     bit
SNC
SNZ
STC
STZ
SUB     fr,#lit
SUB     fr1,fr2
SUB     fr,W
SUBB    fr,bit ***
SWAP    fr
SZ
TEST    fr
XOR     fr,#lit
XOR     fr1,fr2
XOR     fr,W
XOR     W,#lit
XOR     W,fr

* 14-Bit Core Only
** Not supported by PM
*** PM implementation differs from Parallax


17.2. Parallax Instruction Set Reference

ADD    fr,#lit

Add literal into fr

Words : 2  Cycles : 2     Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       addwf    fr      ; fr = fr + W



ADD    fr1,fr2

Add fr2 into fr1

Words : 2  Cycles : 2     Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       addwf    fr1     ; fr1 = fr1 + W



ADD    fr,W

Add W into fr

Words : 1  Cycles : 1     Affects : C, DC, Z

Coding addwf    fr      ; fr = fr + W



ADD    W,#lit              (14-Bit Core)

Add literal into W

Words : 1  Cycles : 1     Affects : W, C, DC, Z

Coding addlw    lit     ; W = W + lit


ADD    W,fr

Add fr into W

Words : 1  Cycles : 1     Affects : W, C, DC, Z

Coding addwf    fr,W    ; W = W + fr



ADDB   fr,bit

Add bit into fr

Words : 2  Cycles : 2     Affects : Z

Coding btfsc    bit     ; If bit = 0, PC = PC+2
       incf     fr      ; fr = fr + 1



AND    fr,#lit

AND literal into fr

Words : 2  Cycles : 2     Affects : W, Z

Coding movlw    lit     ; W = lit
       andwf    fr      ; fr = fr  W



AND    fr1,fr2

AND fr2 into fr1

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr2,W   ; W = fr2
       andwf    fr1     ; fr1 = fr1  W

AND    fr,W

AND W into fr

Words : 1  Cycles : 1     Affects : Z

Coding andwf    fr      ; fr = fr  W



AND    W,#lit

AND literal into W

Words : 1  Cycles : 1     Affects : W, Z

Coding andlw    lit     ; W = W  lit



AND    W,fr

AND fr into W

Words : 1  Cycles : 1     Affects : W, Z

Coding andwf    fr,W    ; W = W  fr



CALL   addr

Call subroutine

Words : 1  Cycles : 2     Affects : None

Coding call     addr   ; Push PC: PC = addr



CJA    fr,#lit,addr

Compare fr to literal and Jump if Above

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       addwf    fr,W    ; W = W + fr
       btfsc    C       ; If fr <= lit, PC = PC+2
       goto     addr    ; PC = addr



CJA    fr1,fr2,addr

Compare fr1 to fr2 and Jump if Above

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr1,W   ; W = fr1
       subwf    fr2,W   ; W = fr2 - W
       btfss    C       ; If frq <= fr2, PC = PC+2
       goto     addr    ; PC = addr



CJAE   fr,#lit,addr

Compare fr to literal and Jump if Above or Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfsc    C       ; If fr < lit, PC = PC+2
       goto     addr    ; PC = addr



CJAE   fr1,fr2,addr

Compare fr1 to fr2 and Jump if Above or Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfsc    C       ; If fr1 < fr2, PC = PC+2
       goto     addr    ; PC = addr



CJB    fr,#lit,addr

Compare fr to literal and Jump if Below

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfss    C       ; If fr >= lit, PC = PC+2
       goto     addr    ; PC = addr



CJB    fr1,fr2,addr

Compare fr1 to fr2 and Jump if Below

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfss    C       ; If fr1 >= fr2, PC = PC+2
       goto     addr    ; PC = addr



CJBE   fr,#lit,addr

Compare fr to literal and Jump if Below or Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       addwf    fr,W    ; W = W + fr
       btfss    C       ; If fr > lit, PC = PC+2
       goto     addr    ; PC = addr



CJBE   fr1,fr2,addr

Compare fr1 to fr2 and Jump if Below or Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr1,W   ; W = fr1
       subwf    fr2,W   ; W = fr2 - W
       btfsc    C       ; If fr1 > fr2, PC = PC+2
       goto     addr    ; PC = addr



CJE    fr,#lit,addr

Compare fr to literal and Jump if Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfsc    Z       ; If fr <> lit, PC = PC+2
       goto     addr    ; PC = addr



CJE    fr1,fr2,addr

Compare fr1 to fr2 and Jump if Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfsc    Z       ; If fr1 <> fr2, PC = PC+2
       goto     addr    ; PC = addr



CJNE   fr,#lit,addr

Compare fr to literal and Jump if Not Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfss    Z       ; If fr = lit, PC = PC+2
       goto     addr    ; PC = addr



CJNE   fr1,fr2,addr

Compare fr1 to fr2 and Jump if Not Equal

Words : 4  Cycles : 4 (5 if jump) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfss    Z       ; If fr1 = fr2, PC = PC+2
       goto     addr    ; PC = addr



CLC

Clear Carry flag

Words : 1  Cycles : 1     Affects : C

Coding bcf      C       ; C = 0



CLR    fr

Clear fr

Words : 1  Cycles : 1     Affects : Z

Coding clrf     fr      ; fr = 0



CLR    W

Clear   W

Words : 1  Cycles : 1     Affects : Z

Coding clrw             ; W = 0



CLR    WDT

Clear WatchDog Timer

Words : 1  Cycles : 1     Affects : TO, PD

Coding clrwdt           ; Reset Watchdog Timer



CLRB   bit

Clear Bit

Words : 1  Cycles : 1     Affects : None

Coding bcf      bit     ; bit = 0



CLZ

Clear Zero flag

Words : 1  Cycles : 1     Affects : Z

Coding bcf      Z       ; Z = 0



CSA    fr,#lit

Compare fr to literal and Skip if Above

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       addwf    fr,W    ; W = W + fr
       btfss    C       ; If fr > lit, PC = PC+2



CSA    fr1,fr2

Compare fr1 to fr2 and Skip if Above

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr1,W   ; W = fr1
       subwf    fr2,W   ; W = fr2 - W
       btfsc    C       ; If fr1 > fr2, PC = PC+2



CSAE   fr,#lit

Compare fr to literal and Skip if Above or Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfss    C       ; If fr >= lit, PC = PC+2



CSAE   fr1,fr2

Compare fr1 to fr2 and Skip if Above or Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfss    C       ; If fr1 >= fr2, PC = PC+2



CSB    fr,#lit

Compare fr to literal and Skip if Below

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfsc    C       ; If fr < lit, PC = PC+2



CSB    fr1,fr2

Compare fr1 to fr2 and Skip if Below

Words :   Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfsc    C       ; If fr1 < fr2, PC = PC+2



CSBE   fr,#lit

Compare fr to literal and Skip if Below or Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       addwf    fr,W    ; W = W + fr
       btfsc    C       ; If fr <= lit, PC = PC+2



CSBE   fr1,fr2

Compare fr1 to fr2 and Skip if Below or Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr1,W   ; W = fr1
       subwf    fr2,W   ; W = fr2 - W
       btfss    C       ; If fr1 <= fr2, PC = PC+2



CSE    fr,#lit

Compare fr to literal and Skip if Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfss    Z       ; If fr = lit, PC = PC+2



CSE    fr1,fr2

Compare fr1 to fr2 and Skip if Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfss    Z       ; If fr1 = fr2, PC = PC+2



CSNE   fr,#lit

Compare fr to literal and Skip if Not Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr,W    ; W = fr - W
       btfsc    Z       ; If fr <> lit, PC = PC+2



CSNE   fr1,fr2

Compare fr1 to fr2 and Skip if Not Equal

Words : 3  Cycles : 3 (4 if skip) Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1,W   ; W = fr1 - W
       btfsc    Z       ; If fr1 <> fr2, PC = PC+2



DEC    fr

Decrement fr

Words : 1  Cycles : 1     Affects : Z

Coding decf     fr      ; fr = fr - 1



DECSZ  fr

Decrement fr and Skip if Zero

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding decfsz   fr      ; fr = fr-1: If 0,PC = PC+2



DJNZ   fr,addr

Decrement fr and Jump if Not Zero

Words :   Cycles : 2 (3 if jump) Affects : None

Coding decfsz   fr      ; fr = fr-1: If 0,PC = PC+2
       goto     addr    ; PC = addr



IJNZ   fr,addr

Increment fr and Jump if Not Zero

Words :   Cycles : 2 (3 if jump) Affects : None

Coding incfsz   fr      ; fr = fr+1: If 0,PC = PC+2
       goto     addr    ; PC = addr



INC    fr

Increment fr

Words : 1  Cycles : 1     Affects : Z

Coding incf     fr      ; fr = fr + 1



INCSZ  fr

Increment fr and Skip if Zero

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding incfsz   fr      ; fr = fr+1: If 0,PC = PC+2



JB     bit,addr

Jump if Bit

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfsc    bit     ; If bit = 0, PC = PC+2
       goto     addr    ; PC = addr


JC     addr

Jump if Carry

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfsc    C       ; If C = 0, PC = PC+2
       goto     addr    ; PC = addr



JMP    addr

Goto address

Words : 1  Cycles : 2     Affects : None

Coding goto     addr    ; PC = addr



JMP    PC+W

Skip W+1 instructions

Words : 1  Cycles : 2     Affects : C, DC, Z

Coding addwf    PCL     ; PC = PC+W+1



JMP    W

Jump to W

Words : 1  Cycles : 2     Affects : None

Coding movwf    PCL     ; PC = (PCLATH<<8) + W



JNB    bit,addr

Jump if Not Bit

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfss    bit     ; If bit = 1, PC = PC+2
       goto     addr    ; PC = addr



JNC    addr

Jump if Not Carry

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfss    C       ; If C = 1, PC = PC+2
       goto     addr    ; PC = addr



JNZ    addr

Jump if Not Zero

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfss    Z       ; If Z = 1, PC = PC+2
       goto     addr    ; PC = addr



JZ     addr

Jump if Zero

Words : 2  Cycles : 2 (3 if jump) Affects : None

Coding btfsc    Z       ; If Z = 0, PC = PC+2
       goto     addr    ; PC = addr



LCALL  addr

Long Call

Words : 1-3  Cycles : 2-4   Affects : None

Coding[ bcf/bsf PCLATH.4 ]      ; Set if 8K Code
      [ bcf/bsf PCLATH.3  ]     ; Set if 4K or 8K Code
        call    addr            ; Push PC: PC = addr



LJMP   addr

Long Jump

Words : 1-3  Cycles : 2-4   Affects : None

Coding[ bcf/bsf PCLATH.4 ]      ; Set if 8K Code
      [ bcf/bsf PCLATH.3  ]     ; Set if 4K or 8K Code
        goto    addr            ; PC = addr



LSET   addr

Long Set

Words : 0-2  Cycles : 0-2   Affects : None

Coding[ bcf/bsf PCLATH.4 ]      ; Set if 8K Code
      [ bcf/bsf PCLATH.3  ]     ; Set if 4K or 8K Code



MOV    fr,#lit

Move literal into fr

Words : 2  Cycles : 2     Affects : W

Coding movlw    lit     ; W = lit
       movwf    fr      ; fr = W



MOV    fr1,fr2

Move fr2 to fr1

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr2,W   ; W = fr2
       movwf    fr1     ; fr1 = W



MOV    fr,W

Move W into fr

Words : 1  Cycles : 1     Affects : None

Coding movwf    fr      ; fr = W



MOV    OPTION,#lit

Move literal into OPTION

Words : 2  Cycles : 2     Affects : W

Coding movlw    lit     ; W = lit
       option           ; OPTION = W



MOV    OPTION,fr

Move fr into OPTION

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr,W    ; W = fr
       option           ; OPTION = W



MOV    OPTION,W

Move W into OPTION

Words : 1  Cycles : 1     Affects : None

Coding option           ; OPTION = W



MOV    !fr,#lit

Move literal into fr's TRIS register

Words : 2  Cycles : 2     Affects : W

Coding movlw    lit     ; W = lit
       tris     fr      ; TRIS(fr) = W



MOV    !fr1,fr2

Move fr2 into fr's TRIS register

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr2,W    ; W = fr2
       tris     fr1      ; TRIS(fr1) = W



MOV    !fr,W

Move W into fr's TRIS register

Words : 1  Cycles : 1     Affects : W

Coding tris     fr      ; TRIS(fr) = W



MOV    W,#lit

Move literal into W

Words : 1  Cycles : 1     Affects : W

Coding movlw    lit     ; W = lit



MOV    W,fr

Move fr into W

Words : 1  Cycles : 1     Affects : W, Z

Coding movf     fr,W    ; W = fr



MOV    W,/fr

Move complement of fr into W

Words : 1  Cycles : 1     Affects : W, Z

Coding comf     fr,W    ; W = ~fr



MOV    W,fr-W            (No PM Support)

Move fr-W into W

Words : 1  Cycles : 1     Affects : W, C, DC, Z

Coding subwf    fr,W    ; W = fr - W



MOV    W,++fr

Move fr+1 into W

Words : 1  Cycles : 1     Affects : W, Z

Coding incf     fr,W    ; W = fr + 1



MOV    W,--fr

Move fr-1 into W

Words : 1  Cycles : 1     Affects : W, Z

Coding decf     fr,W    ; W = fr - 1



MOV    W,<<fr

Move value of fr rotated left through carry into W

Words : 1  Cycles : 1     Affects : W, C

Coding rlf      fr,W    ; C = fr.7: W = (fr<<1)|C



MOV    W,>>fr

Move value of fr rotated right through carry into W

Words : 1  Cycles : 1     Affects : W, C

Coding rrf      fr,W    ; C = fr.0: W = C|(fr>>1)



MOV    W,<>fr

Move nibble swapped value of fr into W

Words : 1  Cycles : 1     Affects : W

Coding swapf    fr,W    ; W = fr[3..0]|fr[7..4]



MOVB   bit1,bit2

Move bit2 into bit1

Words : 4  Cycles : 4     Affects : None

Coding btfss    bit2    ; If bit2 = 1, PC = PC+2
       bcf      bit1    ; bit1 = 0
       btfsc    bit2    ; If bit2 = 0, PC = PC+2
       bsf      bit1    ; bit1 = 1



MOVB   bit1,/bit2

Move complement of bit2 into bit1

Words : 4  Cycles : 4     Affects : None

Coding btfsc    bit2    ; If bit2 = 0, PC = PC+2
       bcf      bit1    ; bit1 = 0
       btfss    bit2    ; If bit2 = 1, PC = PC+2
       bsf      bit1    ; bit1 = 1



MOVSZ  W,++fr

Move fr+1 into W and Skip if Zero

Words : 1  Cycles : 1 (2 if skip) Affects : W

Coding incfsz   fr,W    ; W = fr+1: If 0, PC = PC+2



MOVSZ  W,--fr

Move fr-1 into W and Skip if Zero

Words : 1  Cycles : 1 (2 if skip) Affects : W

Coding decfsz   fr,W    ; W = fr-1: If 0, PC = PC+2



NEG    fr

Negate fr

Words : 2  Cycles : 2     Affects : Z

Coding comf     fr      ; fr = ~fr
       incf     fr      ; fr = fr + 1



NOP

No Operation

Words : 1  Cycles : 1     Affects : None

Coding nop              ; Do Nothing!!!



NOT    fr

Complement fr

Words : 1  Cycles : 1     Affects : Z

Coding comf     fr      ; fr = ~fr



NOT    W

Complement W

Words : 1  Cycles : 1     Affects : Z

Coding xorlw    0FFh    ; W = W ^ 0FFh



OR     fr,#lit

OR literal into fr

Words : 2  Cycles : 2     Affects : W, Z

Coding movlw    lit     ; W = lit
       iorwf    fr      ; fr = fr  W



OR     fr1,fr2

OR fr2 into fr1

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr2,W   ; W = fr2
       iorwf    fr1     ; fr1 = fr1  W



OR     fr,W

OR W into fr

Words : 1  Cycles : 1     Affects : Z

Coding iorwf    fr      ; fr = fr  W



OR     W,#lit

OR literal into W

Words : 1  Cycles : 1     Affects : W, Z

Coding iorlw    lit     ; W = W  lit



OR     W,fr

OR fr into W

Words : 1  Cycles : 1     Affects : W, Z

Coding iorwf    fr,W    ; W = W  fr



RET                    (12-Bit Core)

Return from subroutine

Words : 1  Cycles : 2     Affects : W

Coding retlw    0       ; W = 0: Pop PC



RET                    (14-Bit Core)

Return from subroutine

Words : 1  Cycles : 2     Affects : None

Coding return           ; Pop PC



RETI                   (14-Bit Core)

Return from interrupt

Words : 1  Cycles : 2     Affects : None

Coding retfie           ; Pop PC



RETW   lit1,lit2,...

Return from subroutine with value(s) in W

Words : ?  Cycles : 2     Affects : W

Coding  retlw   lit1    ; W = lit1: Pop PC
      [ retlw   lit2 ]  ; W = lit2: Pop PC
        ...



RL     fr

Rotate left fr through carry

Words : 1  Cycles : 1     Affects : C

Coding rlf      fr      ; C = fr.7: fr = (fr<<1)|C


RR     fr

Rotate right fr through carry

Words : 1  Cycles : 1     Affects : C

Coding rrf      fr      ; C = fr.0: fr = C|(fr>>1)



SB     bit

Skip if Bit

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfss    bit     ; If bit = 0, PC = PC+2



SC

Skip if Carry

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfss    C       ; If C = 0, PC = PC+2



SETB   bit

Set Bit

Words : 1  Cycles : 1     Affects : None

Coding bsf      bit     ; bit = 1



SKIP

Skip next instruction

Words : 1  Cycles : 2     Affects : None

Coding btfss    4,7     ; PC = PC+2



SLEEP

Enter Sleep mode

Words : 1  Cycles : 1     Affects : TO, PD

Coding sleep            ; Enter Low Power Mode



SNB    bit

Skip if Not Bit

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfsc    bit     ; If bit = 0, PC = PC+2



SNC

Skip if Not Carry

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfsc    C       ; If C = 0, PC = PC+2



SNZ

Skip if Not Zero

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfsc    Z       ; If Z = 0, PC = PC+2



STC

Set Carry

Words : 1  Cycles : 1     Affects : C

Coding bsf      C       ; C = 1



STZ

Set Zero

Words : 1  Cycles : 1     Affects : Z

Coding bsf      Z       ; Z = 1



SUB    fr,#lit

Subtract literal from fr

Words : 2  Cycles : 2     Affects : W, C, DC, Z

Coding movlw    lit     ; W = lit
       subwf    fr      ; fr = fr - W



SUB    fr1,fr2

Subtract fr2 from fr1

Words : 2  Cycles : 2     Affects : W, C, DC, Z

Coding movf     fr2,W   ; W = fr2
       subwf    fr1     ; fr1 = fr1 - W


SUB    fr,W

Subtract W from fr

Words : 1  Cycles : 1     Affects : C, DC, Z

Coding subwf    fr      ; fr = fr - W



SUBB   fr,bit

Subtract bit from fr

Words : 2  Cycles : 2     Affects : Z (if bit = 1)

Coding btfsc    bit     ; If bit = 0, PC = PC+2
       decf     fr      ; fr = fr - 1



SWAP   fr

Swap nibble in fr

Words : 1  Cycles : 1     Affects : None

Coding swapf    fr      ; fr = fr[3..0]|fr[7..4]



SZ

Skip if Zero

Words : 1  Cycles : 1 (2 if skip) Affects : None

Coding btfss    Z       ; If Z = 1, PC = PC+2



TEST   fr

Test fr for zero

Words : 1  Cycles : 1     Affects : Z

Coding movf     fr      ; If fr = 0, Z=1 Else Z=0



XOR    fr,#lit

XOR literal into fr

Words : 2  Cycles : 2     Affects : W, Z

Coding movlw    lit     ; W = lit
       xorwf    fr      ; fr = fr  W



XOR    fr1,fr2

XOR fr2 into fr1

Words : 2  Cycles : 2     Affects : W, Z

Coding movf     fr2,W   ; W = fr2
       xorwf    fr1     ; fr1 = fr1  W


XOR    fr,W

XOR W into fr

Words : 1  Cycles : 1     Affects : Z

Coding xorwf    fr      ; fr = fr  W



XOR    W,#lit

XOR literal into W

Words : 1  Cycles : 1     Affects : W, Z

Coding xorlw    lit     ; W = W  lit



XOR    W,fr

XOR fr into W

Words : 1  Cycles : 1     Affects : W, Z

Coding xorwf    fr,W    ; W = W  fr
