

                   ZSM, a CP/M Z80 assembler.

ZSM is an assembler for the Z80 microprocessor.  It uses standard
Zilog/Mostek   mnemonics,   supports  conditional  assembly   and
produces  Intel HEX file suitable for loading with the CP/M  LOAD
utility.  ZSM is a disk based assembler, i.e. source code is read
from  disk,  the resulting object code is written to disk and  an
optional  print  file can be written to disk.  Alternatively  the
print file can be redirected to the console.

1. Using the assembler.
-----------------------
The assembler is initiated by typing:

          ZSM filename.pqr

This takes the file 'filename.ZSM' and assembles it according  to
the  parameters  'p','q'  and 'r' and  the  options  chosen.  The
parameters must be selected as follows:

     p   - the   disk   drive   containing   the   source   code,
           'filename.ZSM'. A to P or @ for default drive.

     q  - the disk drive where the object code, 'filename.HEX' is
          to be written.  A to P or @ for default drive, Z if not
          required.

     r   - the  disk  drive where the listing is to  be  written,
          'filename.PRN'.  A to O or @ for  default drive,  P  to
          the  list device,  X to the console,  Y to the  console
          with errors to the pinter, Z to suppress listing.

For example assembling the file TEST.ZSM:-

     ZSM TEST.AAB

This expects the file TEST.Z80 on drive A,  will write the object
code file,  TEST.HEX to drive A and the listing file, TEST.PRN to
drive  B.


















                                1



2. Assembler syntax
-------------------
2.1 ASSEMBLER MNEMONICS
The assembler recognises all standard Z80 mnemonics as defined in
the  Z80  CPU  Technical  Manual.  The  following  mnemonics  are
recognised in both forms shown.

     ADC A,s        ADC s
     ADD A,n        ADD n
     ADD A,r        ADD r
     ADD a,(HL)     ADD (HL)
     ADD a,(IX+d)   ADD (IX+d)
     ADD a,(IY+d)   ADD (IY+d)

2.2 LABELS
Labels  may be up to 11 characters long.  The first character  of
the label must be alphabetic (i.e.  A-Z) or '_' or '$'.  A colon,
':' following the label is optional.

2.3 CONSTANTS
ZSM  allows  binary,   octal,   decimal,  hexadecimal  and  ASCII
constants according to the following conventions:

Binary - number formed from binary digits (0,1) and terminated by
the character 'B'. Range 0000000000000000B to 1111111111111111B.

Example:       LD HL,10001111101101B

Octal  - number formed from octal digits (0-7) and terminated  by
the character 'Q'. Range 000000Q to 177777Q.

Example:       LD HL,23670Q

Decimal - number formed from decimal digits (0-9) and EITHER left
unterminated or terminated by the character 'D'.
Range: 0 to 65535.

Example:       LD HL,32145

Hexadecimal - number formed from hexadecimal digits (0-9 and A-F)
and terminated by the character 'H'.  A hex number beginning with
a  letter must be preceded by a 0 to distinguish it from a  label
or register name.  Range 0000H to FFFFH.

Example:       LD HL,0A3FH

ASCII  - number formed from ASCII value of characters enclosed in
single  quotes.  Range  ' ' to '~' or 20H to  7EH  including  all
alphanumerics and punctuation.

Examples:      LD HL,'Wk'
               LD A,'*'

The $ sign used as a constant represents the current value of the
program counter.


                                2



2.4 EXPRESSION EVALUATION
Operands in instructions and pseudo-ops may consist of arithmetic
expressions   which  are  evaluated  at  assembly  time  and  the
calculated value used as part of the object code.  The  following
operators may be used to form expressions:

     +              Addition
     -              Subtraction (or unary Negation)
     *              Multiplication
     /              Division
     .MOD.          Modulus
     < or .GT.      Greater Than. X.GT.Y true if X greater than Y.
     .GE.           Greater  than  or  Equal.  X.GE.Y true  if  X
                    greater than or equal to Y.
     > or .LT.      Less Than. X.LT.Y true if X less than Y.
     .LE.           Less  than or Equal.  X.LE.Y true if  X  less
                    than or equal to Y.
     = or .EQ.      Equal. X.EQ.Y true if X equals Y.
     .NE.           Not Equal. X.NE.Y true if X not equal to Y.
     .SHL. n        Shift Left n bits.
     .SHR. n        Shift Right n bits.
     .NOT.          Logical NOT (unary)
     .AND.          Logical AND
     .OR.           Logical OR
     .XOR.          Logical Exclusive OR
     .LOW.          Low byte of expression (.MOD. 256)
     .HIGH.         High byte of expression (.SHR. 8)

Expressions  are evaluated left to right with no  precedence.  No
parentheses  can be used in expressions so some care is  required
to   ensure  that  expressions  are   correctly   formed.   Unary
expressions .NOT.,  .LOW.  and .HIGH. must be at the beginning of
an  expression  and  only  act  on  the  next  parameter  in  the
expression. For example:

     DB        .LOW. 1234H + 50

is evaluated as (.LOW. 1234H) + 50, not .LOW.(1234H + 50).


2.5 PSEUDO-OPCODES

DB or DEFB (define byte)
The  DB pseudo-op tells the assembler to reserve a byte or string
of  bytes  with  specific values.  The bytes may  be  defined  as
constants, expressions as described earlier or as already defines
symbols.

<label>:  DB   <item or list of items>

For example:

          DB   3,-5,34+LABEL,'A'




                                3



DS or DEFS (define storage)
This  tell  the assembler to reserve a specified number of bytes
for  storage.  Note  that  the data stored in the  bytes  is  not
defined.

DW or DEFW (define word)
This  is  exactly the same as the DB Pseudo-op  except  that  the
data is stored in words (2 bytes each) rather than bytes.

END (end of assembly)
This pseudo-op is used to terminate assembly of a block of source
code.

ENDIF (end of IF definition)
Used to terminate a block of conditionally assembled code. See IF
Pseudo-op for further details.

EQU (equate)
The  EQU  pseudo-op  assigns a value to a label  or  symbol.  The
format is:

     label:    EQU  <item>

Label is the name of the symbol and item is any of:  a  constant,
an  address,  a  label or an expression.  Once the value  of  the
symbol is assigned it is in effect for the entire source program.

FORM (form feed)
Forces a new page in the listing.

IF (begin conditional assembly)
The  IF,  ELSE and ENDIF pseudo-ops define a sequence of assembly
language  statements which are to be included or excluded  during
the assembly. The form is:

          IF   <expression>
          statement #1
          statement #2
             .....
          statement #n
         [ELSE
             .....
             .....    ]
          ENDIF

Conditionals  may be nested up to 8 levels deep.  Values used  in
the expression must be defined before the IF statement.  When the
assembler  finds an IF pseudo-op the expression is evaluated.  If
the  expression evaluates to a logical TRUE (non-zero)  then  the
statements  following,  up  to  the  ENDIF are  included  in  the
assembly. The optional ELSE pseudo-op allows alternate code to be
generated when the opposite condition exists.  An ELSE is  always
related to the most recent active IF.




                                4



     IF   <expr1>  -----------+
                              |
     IF   <expr2>  ------+    |
                         |    |
     ELSE ---------------+    |
                         |    |
     ENDIF --------------+    |
                              |
     IF   <expr3> -------+    |
                         |    |
     ENDIF --------------+    |
                              |
     ENDIF -------------------+


LIST (use following options in listing)
This  is used to control what parts of the assembly  listing  get
sent  to the listing file.  The word LIST is followed by a string
of option word separated by commas.

     LIST OFF
     Suppresses the listing until a LIST ON command.

     LIST ON (default)
     Turns on the listing file after a LIST OFF statement.

     LIST COND (default)
     Forces  generation and printing of all blocks of code  which
     are   part  of  conditional  assemblies  whether  they   are
     assembled or not.

     LIST NOCOND
     Suppresses listing of IF,  ELSE and ENDIF statements and any
     conditionally  assembled code which is NOT included  in  the
     assembly,  i.e. only the code actually assembled is shown in
     the listing.

     LIST SYMBOL (default)
     Generate  a  sorted symbol table at the end of  the  listing
     file.

     LIST NOSYMBOL
     Suppress printing of a sorted symbol table at the end of the
     listing file.

     LIST TABS (default)
     Tab characters (ASCII 9) are to be used in the listing file.

     LIST NOTABS
     Do not use tabs in the listing file.







                                5



2.6 COMMENTS
Remarks or comments are free format including any printable ASCII
character as long as the comment is preceded by a semicolon, ';'.
The  comment may follow an opcode,  operand or label or may exist
on a line by itself.

3. Error Messages
ZSM  generates  a number of error messages  while  assembling  to
inform you of its progress. They fall into two categories: errors
found  while  setting up files for assembly operation  and  those
encountered  while assembling the file.  The first type of  error
message will be one of the following:

     Source (.ZSM) file not found.
     Unable to create/open object (.HEX) file.
     Unable to create/open output (.PRN) file.

The first message is generated when the filename specified in the
command  line  cannot be found on the selected  disk.  The  other
messages occur while the output (HEX and PRN) files are being set
up,  usually the disk or directory is full. These errors are sent
only to the console and the assembly is aborted.

The  following errors can occur during the assembly process.  The
offending  source line is displayed on the console,  followed  by
the error message.  If a listing file has been selected the error
message  appears in the listing on the line following the  error.
Errors are displayed even if the listing has been disabled  using
the 'LIST OFF' pseudo-op.

     "Too many IF statements"
     Only 8 levels of nested IF statements are allowed

     "ENDIF without matching IF statement"
     IF  and ENDIF should always be paired to indicate the  start
     and end of a section of conditional code.

     "ELSE without matching IF statement"
     The  ELSE  pseudo-op should only appear within a section  of
     conditional code between IF and ENDIF.

     "Relative jump range error"
     The address specified in a relative jump instruction is  out
     of the range -128 to +127.

     "Expression error"
     This error is caused by a badly formed expression. Note that
     brackets are not allowed in expressions.

     "Illegal opcode"
     The assembler cannot recognise the instruction.

     "Multiple definition"
     The  symbol has already been defined.



                                6



     "Syntax error"
     This error message covers a multitude of sins. It is usually
     caused  by misspelling or omission of a delimiter such as  a
     comma or semicolon.

     "Undefined symbol"
     The  symbol  used in the instruction or expression  has  not
     been defined.

     "Value error"
     This error appears when the value of a symbol or  expression
     exceeds  the range allowable.  For example an index register
     displacement value must be in the range +127 to -128.
     "Symbol Table Overflow"

     "Divide by Zero"
     The expression being evaluated contains a division by zero.








































                                7
