KAsm

 

Assembler for

Z80 and 8051 family of microcontrollers


 

 

 

 

User's Guide

ver. 1.1

Author: Marko Klopcic

 

 

 

 

 

 


License

  This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

Introduction

The main reason (requirement) for KAsm implementation was compilation of tons of existing Z80 assembler programs. The next requirement defined the format of two output files. The first one is LST file, which contains compiled hex codes and source. The second output file should be in Intel Hex format.

Java was chosen as implementation language, because of high productivity and portability. The speed is not a problem, since 22000 lines of assembler program generating 93 kB Intel hex file is compiled in about 700 ms on Athlon 64, 3000+.

The code is well commented and easy to customize, so it is easy to adapt syntax, produce additional output, or even implement assembler for another microprocessor.

The later statement has been proven in March 2010 (ver. 1.1), when assembler for Intel's 8051 and its derivatives was implemented. Furthermore three new directives were added also to Z80 assembler.

Installation and Running

Since KAsm is written in Java, it should run on any machine or operating system, where Java runs. The distribution is compiled with Java 1.6, but sources can also be compiled with Java 1.5, if needed. Ant build file is included in the source distribution.

To use the program, unzip it to local disk. Then you can run it as executable jar file, for example:

$ java -jar /myprograms/kasm/KAsm.jar myProgram.asm


Usage

All command line arguments can be displayed with option -h. Version 1.1 prints the following text:
$ java -jar KAsm-1.1.jar -h

KAsm, Z80 Assembler
(c) Marko Klopcic, Mar 2009

Usage : KAsm [options] <sourceFileName>
Examples: KAsm -f -c -e COMPILE_ALL=1 -e COMPILE_FLOAT=0 myZ80prog.asm
KAsm -s 8051 -f -c -e COMPILE_ALL=1 -e COMPILE_FLOAT=0 my8051prog.asm
Options:
-h --help prints this help
-s --processor <processorType> : target processor. Currently 'z80' and
'8051' are supported. If not
specified, 'z80' is assumed.
-l --lstname <lstFileName> : name of LST output file.
Default: <filename>.lst
-x --hexname <hexFileName> : name of HEX output file.
Default: <filename>.hex
-b --binname <binFileName> : name of binary output file. If not specified,
no binary file is created.
-c --constants add std constants to expression parser: 'e' and 'pi'
-f --functions add std functions to expression parser: ln, acos, atan,
asin, cos, sin, tan, sqrt, sum, log, add umin, rand
-p --profile prints time spent in each step of compilation
-r --reserved reserved words (reg. names) may be used for labels and
constants.
-e --equ <const definition> : define constant. There must be no spaces
next to '='. Example: -e COMPILE_ALL=1
-t --truncate <len of bin file> : truncate bin file at the specified offset
Example: -t 32768

If standard constants and/or functions are added to expression parser, then they may be used in expressions, for example:
        ld HL, AMPLITUDE * sin(pi/4) 
If option -r, --reserved is not specified, then names of registers are not allowed for labels and constants. For example, the following line will issue an error:
HL:     LD A, C
The option -r, --reserved should be used only for compatibility reasons.

Assembler syntax

Labels and constants

Many rules for labels and constants defined with EQU directive, are the same:
  1. All labels must be followed by ':', while for constants, which are defind by EQU and similar directives,  ':' is optional.
  2. It is not required that labels and constants begin in column 1 - they may be preceeded by spaces or tabs.
  3. Labels and constants are not case sensitive.
  4. Labels and constants must start with letter or underscore character ('_'). They may contain letters, numbers, underscore and dot.
  5. Labels and constants may not be equal to register names.

Examples

Valid definitions:

HEADER_LEN    equ 256
noOfPages: equ 10
LBL1: ld A, 10

_LBL.2:
ret
Invalid definitions:
#COMM_DELAY: EQU 100   ; invalid first character
LABEL ld a, 5 ; label must be terminated with ':'
.LBL1: ; label must not start with '.'
9LBLA: ; label must not start with number
HL: ; HL is register, may not be used as a label
Definitions of constants may not include labels, which are defined later in the program, because constants must be evaluated in compilation pass 1.

Labels may be defined only once, otherwise an error is reported. If constant is defined many times, only warning is reported, because sometimes one may want to redefine the constant (which should normally remain constant, that's why the warning is issued).

Constants may be defined with expressions, which may also include other constants, but only those which are defined in lines before the current one.

Examples

Valid constant definitions:

TRUE          EQU 1
BUFFER_SIZE EQU 128
SECTION_SIZE EQU BUFFER_SIZE/8
Invalid constant definitions
CHECKSUM_OFFSET: EQU HEADER_LEN - 1  ; HEADER_LEN not defined before this line 
HEADER_LEN: EQU 100

Comments

Comments start with ';' and extend to the end of the line.

Examples

; comment line
ld a, 20 ; comment
lbl1: ; comment

Literal constants

Numbers

Numbers may be written in binary, decimal, and hexadecimal notation. Binary numbers may contain only 0s and 1s and the last character must be 'B' or 'b'. Hexadecimal numbers must begin with a number character (0-9) and end with character 'H' or 'h'. Examples
10   - decimal number ten
10B - binary number two
10H - hexadecimal number sixteen
0ffh - hexadecimal number (255). Note the leading 0, which must be present, because the
number would otherwise start with a letter

Charactes

Characters are decoded as 8 bit ASCII values. They must be written between single or double quotes.

Examples

   'a' - single qotes
"B" - double quotes

Strings

Strings can be used only as arguments of DB directive. They are written as a set of characters between single or double quotes. Each character in a string compiles as one 8-bit value. Escaping is not supported, so if you want to write double quote character in a string, then use single quotes as string delimiters, and the other way around.

Examples

   'He said: "Hello!"'
"Hi there! I'm letter 'A'!"

Expressions

Expressions can be used anywhere, where literal value can be used: Examples
              ld HL, 10*205 +3
ld a, (HELLO_TEXT + 3)
NO_OF_ITEMS equ 100*3

ld a, (ix + HEADER_LEN * 2)
db ' ' + 20 * 3

Compiler directives

<constant> EQU <expr>

This directive is used to define constants, which may be used in expressions as arguments of assembler instructions, or for conditional compilation. See section Labels and Constants for detailed description and examples.

ORG <expr>

This directive specifies the memory address, where instructions following it should be compiled.

Example:

        org 250
ld A, 10 ; this instruction will generate code starting at address 250

END

This directive marks the end of the program. Everything after line with this directive is ignored. This directive is not mandatory. If not present, everyting to the end of the file is compiled.

IF <expr>, ELSEIF <expr>, ELSE, ENDIF

These three directives can be used for conditional compilation. It is also possible to use nested IF, ELSEIF, ELSE, ENDIF directives. If statement is executed, if the expression evaluates to non-zero value.

Example:
isFloatingPoint EQU 1  
mode EQU 2

...
IF isFloatingPoint
IF mode = 1
call CONFIGURE_MODE_1
ELSEIF mode = 2
call CONFIGURE_MODE_2
ELSEIF mode = 3
call CONFIGURE_MODE_3
ELSE
call CONFIGURE_DEFAULT_MODE
 ENDIF
ENDIF
...

DB <bytes>, DW <words>

These two directives can be used to define arbitrary data used by the program. Arguments must be separated by commas. They can be anything from literal constants to characters, expressions, or strings (DB only).

The number of items in DB directive is limited to 512, for DW it is 256. This should be more than enough, otherwise the internal buffer should be increased and the program recompiled (see OpCode.MAX_BYTES_PER_ASM_LINE).

Example:

        DB 42, 'b', "hello!", ' ' + 34
DW 42, 'b', ' ' + 34

DS <expr>

This directive tells compiler to leave <expr> number of bytes of uninitialized space.
Example:
        DS  20  

$INCLUDE (<filename>)

This directive includes other file. Instructions and directives are inserted into this file and compiled. It has the same effect as manual copy-paste operation. Nested includes are allowed. <filename> may specify path to include file in relative or absolute way. Relative paths should be relative to current directory, not relative to assembler file.
Example:
        $include (../src/regs500.i)

Z80 assembler specifics

RST instructions

Arguments of RST instructios may be given as:


8051 assembler specifics

Constants

Constants in 8051 can be defined also with directives DATA, IDATA, XDATA, CODE and BIT. However, all constants are definfed in the same namespace so there is no difference between those constants, and constants defined with EQU directive.

JMP and CALL instructions

8051 familiy of microprocessors has three instructions for jumps - SJMP, AJMP, and LJMP. When compiler sees instruction JMP, if first checks if label is laready defined. If it is, and it is less than 128 bytes away, SJMP is used. Otherwise the compiler checks if the address is located in the same 2k blok. If it is, AJMP instruction is used. If even that is not tha ces, LJMP is used.
If label is not defined yet (it is forward jump), then LJMP is always used.
According to these rules, it is recommended to use JMP instruction for backward jumps, while for forward jumps the programmer sbould use the best instruction.

 


  © Marko Klop i , 2009, 2010