Web100

News | Documentation | Hardware | Software | Books | Links

8085 Cross-Assembler (Portable)

Version 0.1
Copyright (c) 1985,1987 William C. Colley, III

The manual such as it is.


Legal Note:

This package may be used for any commercial or non-commercial purpose. It may be copied and distributed freely provided that any fee charged by the distributor of the copy does not exceed the sum of: 1) the cost of the media the copy iswritten on, 2) any required costs of shipping the copy, and 3) a nominal handling fee. Any other distribution requires the written permission of the author. Also, the author's copyright notices shall not be removed from the program source, the program object, or the program documentation.


Table of Contents

1.0 How to Use the Cross-Assembler Package
2.0 Format of Cross-Assembler Source Lines
2.1 Labels
2.2 Numeric Constants
2.3 String Constants
2.4 Expressions
3.0 Machine Opcodes
3.1 Opcodes -- No Argument
3.2 Opcodes -- One Register Argument
3.3 Opcodes -- One RST Vector Argumen
3.4 Opcodes -- One I/O Port Argumet
3.5 Opcodes -- One Immediate Argument
3.6 Opcodes -- One Address Argument
3.7 Opcodes -- Two Register Arguments
3.8 Opcodes -- One Register and One Immediate Argument
3.9 Opcodes -- One Register and One Address Argument
4.0 Pseudo Opcodes
4.1 Pseudo-ops -- DB
4.2 Pseudo-ops -- DS
4.3 Pseudo-ops -- DW
4.4 Pseudo-ops -- END
4.5 Pseudo-ops -- EQU
4.6 Pseudo-ops -- IF, ELSE, ENDIF
4.7 Pseudo-ops -- INCL
4.8 Pseudo-ops -- ORG
4.9 Pseudo-ops -- PAGE
4.10 Pseudo-ops -- SET
4.11 Pseudo-ops -- TITLE
5.0 Assembly Errors
5.1 Error * -- Missing Statement
5.2 Error ( -- Parenthesis Imbalance
5.3 Error " -- Missing Quotation Mark
5.4 Error D -- Illegal Digit
5.5 Error E -- Illegal Expression
5.6 Error I -- IF-ENDIF Imbalance
5.7 Error L -- Illegal Label
5.8 Error M -- Multiply Defined Label
5.9 Error O -- Illegal Opcode
5.10 Error P -- Phasing Error
5.11 Error R -- Illegal Register
5.12 Error S -- Illegal Syntax
5.13 Error T -- Too Many Arguments
5.14 Error U -- Undefined Label
5.15 Error V -- Illegal Value
6.0 Warning Messages
6.1 Warning -- Illegal Option Ignored
6.2 Warning -- -l Option Ignored -- No File Name
6.3 Warning -- -o Option Ignored -- No File Name
6.4 Warning -- Extra Source File Ignored
6.5 Warning -- Extra Listing File Ignored
6.6 Warning -- Extra Object File Ignored
7.0 Fatal Error Messages
7.1 Fatal Error -- No Source File Specified
7.2 Fatal Error -- Source File Did Not Open
7.3 Fatal Error -- Listing File Did Not Open
7.4 Fatal Error -- Object File Did Not Open
7.5 Fatal Error -- Error Reading Source File
7.6 Fatal Error -- Disk or Directory Full
7.7 Fatal Error -- File Stack Overflow
7.8 Fatal Error -- If Stack Overflow
7.9 Fatal Error -- Too Many Symbols



1.0 How to Use the Cross-Assembler Package

First, the question, "What does a cross-assembler do?" needs to be addressed as there is considerable confusion on this point. A cross-assembler is just like any other assembler except that it runs on some CPU other than the one for which it assembles code. For example, this package assembles 8085 source code into 8085 object code, but it runs on an 8088, a 68000, or whatever other CPU you happen to have a C compiler for. The reason that cross-assemblers are useful is that you probably already have a CPU with memory, disk drives, a text editor, an operating system, and all sorts of hard-to-build or expensive facilities on hand. A cross-assembler allows you to use these facilites to develop code for an 8085.

Because this cross-assembler assembles 8085 code, it is, in fact, possible to use it as a regular assembler by compiling it under either Aztec C II or Eco-C and running it on an 8085 under CP/M.

This program requires one input file (your 8085 source code) and zero to two output files (the listing and the object). The input file MUST be specified, or the assembler will bomb on a fatal error. The listing and object files are optional. If no listing file is specified, no listing is generated, and if no object file is specified, no object is generated. If the object file is specified, the object is written to this file in "Intel hexadecimal" format.

The command line for the cross-assembler looks like this:

A85 source_file { >list_file } { -o object_file }

where the { } indicates that the specified item is optional.

Some examples are in order:

a85 test85.asm source: test85.asm
listing: none
object: none

a85 test85.asm -l test85.prn source: test85.asm
listing: test85.prn
object: none

a85 test85.asm -o test85.hex source: test85.asm
listing: none
object: test85.hex

a85 test85.asm -l test85.prn -o test85.hex
source: test85.asm
listing: test85.prn
object: test85.hex


The order in which the source, listing, and object files are specified does not matter. Note that no default file name extensions are supplied by the assembler as this gives rise to portability problems.

2.0 Format of Cross-Assembler Source Lines

The source file that the cross-assembler processes into a listing and an object is an ASCII text file that you can prepare with whatever editor you have at hand. The most-significant (parity) bit of each character is cleared as the character is read from disk by the cross-assembler, so editors that set this bit (such as WordStar's document mode) should not bother this program. All printing characters, the ASCII TAB character (09H), and newline character(s) are processed by the assembler. All other characters are passed through to the listing file, but are otherwise ignored.

The source file is divided into lines by newline char-acter(s). The internal buffers of the cross-assembler will accommodate lines of up to 255 characters which should be more than ample for almost any job. If you must use longer lines, change the constant MAXLINE in file A85.H and recompile the cross-assembler. Otherwise, you will overflow the buffers, and the program will mysteriously crash.

Each source line is made up of three fields: the label field, the opcode field, and the argument field. The label field is optional, but if it is present, it must begin in column 1. The opcode field is optional, but if it is present, it must not begin in column 1. If both a label and an opcode are present, one or more spaces and/or TAB characters must separate the two. If the opcode requires arguments, they are placed in the argument field which is separated from the opcode field by one or more spaces and/or TAB characters. Finally, an optional comment can be added to the end of the line. This comment must begin with a semicolon which signals the assembler to pass the rest of the line to the listing and otherwise ignore it. Thus, the source line looks like this:

{label}{ opcode{ arguments}}{;commentary}

where the { } indicates that the specified item is optional.

Some examples are in order:



column 1
v
GRONK LXI H, POINTER ; This line has everything.
MOV A, M ; This line has no label.
BEEP ; This line has no opcode.
; This line has no label and no opcode.
; The previous line has nothing at all.
END ; This line has no argument. 

2.1 Labels

A label is any sequence of alphabetic or numeric characters starting with an alphabetic. The legal alphabetics are:

! # $ % & , . : ? @ [ \ ] ^ _ ` { | } ~ A-Z a-z

The numeric characters are the digits 0-9. Note that "A" is not the same as "a" in a label. This can explain mysterious U (undefined label) errors occurring when a label appears to be defined.

A label is permitted on any line except a line where the opcode is IF, ELSE, or ENDIF. The label is assigned the value of the assembly program counter before any of the rest of the line is processed except when the opcode is EQU, ORG, PAGE, or SET.

Labels can have the same name as opcodes, but they cannot have the same name as operators or registers. The reserved (operator and register) names are:

$ A AND B C D
E EQ GE GT H HIGH
L LE LT LOW M MOD
NE NOT OR PSW SHL SHR
SP XOR


If a label is used in an expression before it is assigned a value, the label is said to be "forward-referenced." For example:

L1 EQU L2 + 1 ; L2 is forward-referenced here.
L2
L3 EQU L2 + 1 ; L2 is not forward-referenced here.

2.2 Numeric Constants

Numeric constants are formed according to the Intel convention. A numeric constant starts with a numeric character (0-9), continues with zero or more digits (0-9, A-F), and ends with an optional base designator. The base designators are H for hexadecimal, none or D for decimal, O or Q for octal, and B for binary. The hex digits a-f are converted to upper case by the assembler. Note that a numeric constant cannot begin with A-F as it would be indistinguishable from a label. Thus, all of the following evaluate to 255 (decimal):

0ffH 255 255D 377O 377Q 11111111B

2.3 String Constants

A string constant is zero or more characters enclosed in either single quotes (' ') or double quotes (" "). Single quotes only match single quotes, and double quotes only match double quotes, so if you want to put a single quote in a string, you can do it like this: "'". In all contexts except the DB statement, the first character or two of the string constant are all that are used. The rest is ignored. Noting that the ASCII codes for "A" and "B" are 41H and 42H, respectively, will explain the following examples:

"" and '' evaluate to 0000H
"A" and 'A' evaluate to 0041H
"AB" evaluates to 4142H


Note that the null string "" is legal and evaluates to 0000H.

2.4 Expressions

An expression is made up of labels, numeric constants, and string constants glued together with arithmetic operators, logical operators, and parentheses in the usual way that algebraic expressions are made. Operators have the following fairly natural order of precedence:

Highest anything in parentheses
unary +, unary -
*, /, MOD, SHL, SHR
binary +, binary -
LT, LE, EQ, GE, GT, NE
NOT
AND
OR, XOR
Lowest HIGH, LOW


A few notes about the various operators are in order:

  1. The remainder operator MOD yields the remainder from dividing its left operand by its right operand.
  2. The shifting operators SHL and SHR shift their left operand to the left or right the number of bits specified by their right operand.
  3. The relational operators LT, LE, EQ, GE, GT, and NE can also be written as <, <= or =<, =, >= or =>, and <> or ><, respectively. They evaluate to 0FFFFH if the statement is true, 0 otherwise.
  4. The logical opeators NOT, AND, OR, and XOR do bitwise operations on their operand(s).
  5. HIGH and LOW extract the high or low byte, of an expression.
  6. The special symbol $ can be used in place of a label or constant to represent the value of the program counter before any of the current line has been processed.

Some examples are in order at this point:

2 + 3 * 4 evaluates to 14
(2 + 3) * 4 evaluates to 20
NOT 11110000B XOR 00001010B evaluates to 00000101B
HIGH 1234H SHL 1 evaluates to 0024H
001Q EQ 0 evaluates to 0
001Q = 2 SHR 1 evaluates to 0FFFFH

All arithmetic is unsigned with overflow from the 16-bit word ignored. Thus:

32768 * 2 evaluates to 0


More to follow....

ureturn.gif (2080 bytes)

Return to: | Documents | Software |