RM-003 ASM 3.0 User's Guide for HASM 3.0, the Advanced Optimizing Assembler for Harris CDP68HC05 Microcontrollers Preliminary Beta Version S E M I C O N D U C T O R Table of Contents 1 Introduction 1 What is HASM? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 What's New With HASM 3.0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Definition of Terms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Licensing Agreement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 Questions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 2 Using HASM 3.0 5 Running HASM From the Command Line . . . . . . . . . . . . . . . . . . 5 Command Line Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 Setting the standard search path . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 Using DOS batch files to manage HASM switches . . . . . . . . . . . . . . . 8 Output File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 Hex File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Listing File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Error File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Symbol File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 Source File Syntax 10 11 13 14 17 Comments and Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 Mnemonics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Numbering Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 Expressions and Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Addressing Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Inherent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Immediate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extended . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Direct . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Indexed. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Relative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Bit test and branch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 22 22 22 23 24 24 Supported Opcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 HASM 3.0 User's Guide i Table of Contents 4 Assembler Directives 27 Data Allocation Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .27 .ascii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 boolean . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 byte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 .byte. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 char . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 db . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 ds. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 dw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 equ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 fcb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 fdb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 hex. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 integer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 org . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 rmb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 rmw . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 section . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 .word . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 word. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 Control Pragmas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33 else . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 elseif . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 endif. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 endmacro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 endrepeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 error . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 if. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 ifnot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 list . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 macroend . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 nolist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 noopt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 opt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 page . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 ii Table of Contents set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 setnot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 5 User Defined Macros 43 What is a Macro? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Defining a Macro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Labels and Comments in Macros . . . . . . . . . . . . . . . . . . . . . . . . . 44 Passing Arguments to Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . 46 Nested and Recursive Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 6 Optimization 49 Optimized Assembly Language? . . . . . . . . . . . . . . . . . . . . . . . . . 49 Enabling Optimization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 How Optimization is Done . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 Optimization of Indexed Addressing. . . . . . . . . . . . . . . . . . . . . . . . . . . 50 Optimization of Extended Jumps/Subroutine Calls . . . . . . . . . . . . . . . 51 A Errors and Warnings A1 Error Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A1 Warning Messages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A5 Special Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A6 B HASM 3.0 Quick Reference B1 Command Line Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B1 Arithmetic, Logic and Comparative Operators . . . . . . . . . . . . . . B2 Assembler Directives and Pragmas . . . . . . . . . . . . . . . . . . . . . . . B3 HASM 3.0 User's Guide iii Table of Contents iv Introduction 1 1 What is HASM? HASM is a DOS based program for IBM PC compatible computers that allows users to assemble standard 68HC05 assembly language files into machine code for the Harris CDP68HC05 family of 8 bit microcontrollers (MCUs). HASM requires an IBM compatible PC running DOS 4.0 or later (HASM will run under the MSDOS prompt shell in Windows 95), 500kB free memory, and one disk drive. What's New With HASM 3.0 HASM 3.0 is the latest version of the free Harris assembler for the CDP68HC05 family of MCUs. HASM 3.0 includes significant enhancements over HASM 2.7, including: * * * * * * * Optimization for JMPs, JSRs, and indexed addressing Support for user defined macros, including parameter passing New "standard search path" directive for code portability Flexible filenaming conventions Cycle time added to listing file output for easy calculation of processor timing Comparative operators (<, >, and =) added to arithmetic functions Additional assembler directives including set, setnot, error, opt, and noopt. * Support for other types of if-else directives including esleif and ifnot * Support for addition pragma delimiters "$" and "/" in addition to "#" * Support for "$" as the current program location in addition to "*" Most of the new functions have been added so that HASM 3.0 is capable of assembling virtually any assembly code source file written for other 68HC05 assemblers. Definition of Terms The following terms are used throughout this document and are defined as follows: HASM 3.0 User's Guide 1 1 Introduction Installation * source code - this is the program, written in the CDP68HC05 mnemonic assembly language, to be assembled and eventually stored in the memory of a CDP68HC05 microcontroller. It is an ASCII file that can be created with any ASCII text editor. * machine code - this is the hexadecimal language executed by the CDP68HC05 CPU. Machine code is result of assembled source code. Also known as executable code. * assemble - the process of converting source code into machine code. * mnemonic - three, four or five letter "psuedowords" that are assigned directly to CDP68HC05 machine instructions. Mnemonics are the basis of all assembly languages. * pragma - pragmas are special words, delimited with either a "#", "$" or "/", that give the assembler instructions on how to assemble the file. * macro - a macro is a user defined sequence of commands to be executed by the assembler each time the macro name is encountered. Installation Distribution for HASM 3.0 is provided by Harris Semiconductor on 3.5 inch high density (1.44MB) PC compatible diskettes. A copy of HASM 3.0 can also be obtained via the Internet from the Harris CDP68HC05 web page at http:// www.semi.harris.com/68hc05. The copies distributed on diskette are uncompressed and ready to run. The copies downloaded via the internet are compressed and should be unzipped with PKZIP or compatible software decompression tools. It is recommended the HASM 3.0 be installed directly to and run from your computer's hard drive. If necessary, HASM may be run from the floppy drive. HASM is a single file program; there are no initialization or library file associated with it. As such, the executable file, HASM.EXE, may be installed to your computer's hard drive in any directory appropriate. Licensing Agreement HASM 3.0 is a free application produced by Harris Semiconductor, a division of Harris Corporation, for the express use of it's customers and those interested in the Harris CDP68HC05 family of microcontrollers. Since it is freeware, this software may not be sold but may be distributed freely for the express purpose of developing software for CDP68HC05 MCUs. 2 Introduction Questions HASM 3.0 is the property of Harris Corporation and is protected by copyright laws of the United States. The user may not alter or in anyway change the functionality or source code of HASM 3.0 and are prohibited from disassembling the HASM source code into a human readable form for any purpose. Questions As with any product, users at times have questions about functionality and other aspects of HASM. If question arise, please feel free to contact us at Harris Semiconductor by phone at 1-800-4HARRIS or send email to digiApps@harris.com. HASM 3.0 User's Guide 3 1 4 Introduction Questions Using HASM 3.0 2 2 HASM 3.0 provides a development platform for creating software for the Harris CDP68HC05 family of microcontrollers. This chapter explains the basic workings of HASM, including how to assemble source files, input and output file formats, file naming conventions, and command line switches. HASM is a full, symbolic command line assembler for the 68HC05. It supports a wide range of styles for input formats and generates listing type output (source file merged with hex output), `S-record' style hex file output, symbol files for use with Harris development tools and error files for easier debugging. The S-record hex file format is compatible with all Harris 68HC05 development systems. Running HASM From the Command Line HASM is invoked to assemble files directly from the DOS prompt. The input file for HASM should be a standard text file. Control codes should be removed and if the file is generated with a word processor such as WordStar or WordPerfect, the file should be saved in TEXT or NON-DOCUMENT mode. An input file can have any legal DOS (i.e 8.3 format) name. The syntax of invoking HASM is: HASM [/option] [/option] ... [/option] Where is the source file to be assembled and [/option] refers to any of the optional command line switch used to configure HASM. For example, if the file mysource.s is in the current directory, it could be assembled with the following command: HASM mysource.s /l /o /i=c:\6805 The next section describes the function and usage of the command line switches. Command Line Switches When called to assemble a source file, HASM can be passes a sequence of up to nine optional command line switches to set parameters within the assembler and affect the way HASM generates output files. None of these switches are required; if omitted HASM will use default values. All command line switches should be preceeded with a forward slash ( / ) and should not contain spaces. A listing of the HASM command line switches, default values and their functions are shown in HASM 3.0 User's Guide 5 2 Using HASM 3.0 Command Line Switches Table 1. HASM command line switches may be entered in either upper or lower case. Note that some switches have parts that are optional. These parts are shown in the table in square brackets ( [ and ] ). Table 1. HASM Command Line Switches Switch Function Default E[=ext] Controls the generation of the error listing file. If included, a text file will be created with the filename source.erl, where source.s is the assembled source file. If the optional =ext is included, the error filename will have the extension set by ext. Errors are sent to the screen. H Turns off the generation of the S-record hex file. Hex file generated I=path Sets the standard search path for HASM. This path is searched whenever files are included in the source using the #include convention. Standard search path set to /6805/include L[=ext] Controls the generation of the listing file. If included, a listing file will be created with the filename source.lst, where source.s is the assembled source file. If the optional =ext is included, the listing filename will have the extension set by ext. No listing file created M Suppresses the expansion of user defined macros in the listing file. Macros are expanded in the listing file O Enables HASM's multi-pass optimization of JMPs, JSRs, and indexed addressing. No optimization is done S Creates a symbol file with the filename source.sym, where source.s is the assembled source file. No symbol file created W Suppresses the generation of warnings in the error file Warnings are displayed Used to specify the extension of the S-record hex file generated by HASM. The filename of the hex file will be source.ext, where source.s is the assembled source file. Hex file generated with the .H extension. X=ext 6 Using HASM 3.0 Command Line Switches For example, if HASM is called to assemble a file like so: C:\HASM source.s /e=err /l /o /x=s19 /m /i=\6805 HASM will search the current workling directory for the file source.s. If found, HASM will open source.s for assembly. During assembly, HASM will create a hex file, a listing file and an error file. The source file will be assembled with optimization on (see Chapter 6), it will not expand macros in the listing file (see Chapter 5), and the standard search path will be set to C:\6805. Assuming the assembly was a success, the following files will be created: * source.s19 - S-record hex file * source.lst - listing file (macros not expanded) * source.err - error file listing. Setting the standard search path While most of the command line switches used in HASM are very simple and straight forward, the standard search path switch, /i, can be confusing and requires a little more explanation. The purpose of the standard search path in HASM is to allow for code portability. Often a program may have to move from computer to computer before it is completed. A lot of 68HC05 programs use the #include pragma (see Chapter 4 for more details on HASM pragmas) to include a standard files like register mapping files or math subroutines. For those who do a lot of 68HC05 programming, these standard files generally reside in one central location on their machine as opposed to having a single copy in each project directory. As such, the #include directive pointing to these files usually includes a path to get to these files. If you try to assemble the code on a different machine and the the mapping files are in a different path, the assembler will generate errors because it can not find the files. For example, lets say you have three standard files that you include with most of you 68HC05 source files. These files are c16b.s, math.s, and io.s. Now, on you desktop machine at work, these files are in the directory D:\6805. Typically, you would include these files like so: #include d:\6805\c16b.s #include d:\6805\math.s #include d:\6805\io.s This is fine if this code will only ever be assembled on your desktop machine. Now, say you give the code to a coworker to make some edits. She has all of the same files on her machine, but there are located in the C:\hc05\files directory. So now she has to change the #include statements to look like this: HASM 3.0 User's Guide 7 2 Using HASM 3.0 Command Line Switches #include C:\hc05\files\c16b.s #include C:\hc05\files\math.s #include C:\hc05\files\io.s Then, when you get the code back, you have to change them back, and so on. To avoid all of this, the standard search path was invented. When calling HASM to assemble a file, use the /i=path switch to set the standard search path. Then, when HASM encounters any files (without pathes) included in angle brackets ( < and > ), it will search the standard search path. Thus, if the example code above is rewritten like so: #include #include #include You can assemble the code with /i=d:\6805 and your coworker can assemble it with /i=c:\hc05\files and both assemblies will be successful (assuming there are no problems with your code, of course). In addition to allowing you to move code from computer to computer without rewriting you include directives, the standard search path allows you to create one central library directory on your machine for all of your 68HC05 include files and include these files in your programs using the #include directive. No longer do you have four or five copies of the same file in different project directories, which leads to problems when you find an error in one of the files and have to revise all of the copies on your hard drive. The next section describes how to use DOS batch files to allow you to set your standard search path once and not have to type it in every time you assemble a file with HASM. Using DOS batch files to manage HASM switches HASM has a total of nine possible command line switches to be enetered, in addition to the source file name, every time you assemble a file. If you want to change filename extensions or use the standard search path, the process of invoking the assembler with the right configuration can become even more cumbersome. Fortunately, there is a simple solution to this problem build right into the DOS operating system. Most programmers have specific ways they like to assemble their source code. Programmer A might always generate a listing file, an error file with the .err extension, suppress macros and use optimization. Programmer B might always want the listing file, optimization, hex file with the .s19 extension, and set the stan- 8 Using HASM 3.0 Command Line Switches dard search path. By writing a simple DOS batch file, these programmers can set up their HASM command line once and use the batch file to call HASM for them. What is a DOS batch file? A DOS batch file is a simple text file that contains a list of commands for DOS to execute. These commands are the same ones that you would type in at the command prompt. All batch files must have the filename extension .BAT. Parameters can be passed to a batch file by using the "%n" operator, where n is the nth parameter passed. Example 1 shows hasm1.bat, a HASM batch file for Programmer A. Note: on Programmer A's machine HASM is in the 6805 directory on the F:\ drive. Example 1. Sample HASM batch file - HASM1.BAT rem HASM batch file HASM1.BAT f:\6805\hasm.exe %1 /l /e=err /m /o Notice the "%1" after hasm.exe. This is where the name of the source file will be passed to the batch file. The first line in the file, beginning with rem, is a comment line and is not required. To use this file, Programmer A would simply type at the DOS prompt: C:\ hasm1 mycode.s Assuming that the batch file was in his DOS search path, the following would be executed: C:\ rem HASM batch file HASM1.BAT C:\ f:\6805\hasm.exe mycode.s /l /e=err /m /o And thus HASM would be called with all of Programmer A's desired switches added. Likewise, Example 2 shows Programmer B's batch file, hasm.bat. Example 2. Sample HASM batch file - HASM.BAT rem HASM batch file HASM1.BAT d:\hasm.exe %1 /l /o /i=d:\harris\hc05\files /x=s19 %2 %3 Again you can see how the command line is set up with all of Programmer B's switches. Note the %2 and %3 at the end of the line. These are included to allow for the addition more switches to the ones used frequently. Thus, if Programmer B occasionally wants to suppress macro expansion, he could type at the command prompt: HASM 3.0 User's Guide 9 2 Using HASM 3.0 Output File C:\ hasm code.asm /m and the following would be executed: d:\hasm.exe code.asm /l /o /i=d:\harris\6805\progs /x=s19 /m The %1 was relaced with code.asm and the %2 was replaced with /m. The %3, which was not passed a value, was simply replaced with a space. Some programmers also prefer to write several different batch files for different assembly methods. Thus, DOS batch files can easily manage your HASM command line, no matter how long and complex they get. Output File HASM is capable of generating up to four different types of output files during assembly. These files are the hex file, listing file, error file and the symbol file. A description of each of these file types is given in this section. Hex File The primary output of HASM is the S-record formatted hex file. This file contains the final assembled code in an ASCII hex (i.e. two ASCII characters, like "E" ($45) and "4" ($34), represent the number $E4) format. The hex file is the file used by most development systems and programmers as a representation of the final code. By default, the name of the hex output file is the base of the source filename with the .H extension. For example, of the name of the source file is myfile.asm, the name of the hex file will be myfile.h. Some programmers and development systems prefer the use of other filename extensions for the hex file. To instruct HASM to use a different extension, use the /X= command line switch. For example, if the file myfile.asm is assembled with the command line switch /X=s19, the name of the hex file will be myfile.s19. If the /H switch is used when invoking the assembler the generation of the hex file will be suppressed, even if the /X command is included. HASM creates hex files only in the industry standard "S19" S-record format. This file is an ASCII text file that can be viewed with any standard text editor (e.g. DOS edit.com). Each line in the file, referred to as a record, contains specific information about the file that was assembled. The first two characters in each record describe the format of that record; there are three main types of records in the S19 format. The S0 record is for header and comments. All information contained after the S0 record is ignored. The S1 record is the main data record and contains 10 Using HASM 3.0 Output File all of the addressing and machine code information. Finally, the S9 record is used to indicate the end-of-file for S-record files. The format of these lines is as follows: * S0 This is a comment, this text will be ignored Lines beginning with the S0 characters are comment or header lines. Since programmers rarely if ever edit hex files directly anymore, these lines are seldom used. HASM does not generate any S0 records; they may be added to the hex file if desired. * S1091D408AB67B147183D6 S1 records are the main data records. They consist of the following information: the two character S1 delimiter, a two character byte count, a four character address, data bytes, and a two character checksum. Note that the byte count, unlike Intel hex formats, includes the address and checksum. Since these will always require three bytes, the number of data bytes in a record is three less than the count. Also keep in mind that the count refers to the number of bytes in a record, not the number of ASCII characters required to represent those bytes. In the record shown above, the count is $09 (there are six data bytes), the address is $1D40, the checksum is $D6, and the rest are data bytes. The maximum length of an S1 record is 78 characters. * S9030000FC Finally, the S9 record indicates the end of file for a hex file. It is always of the same format -- S9, count, null address ($0000), and the checksum. Example 3 shows a typical S-record format hex file. Example 3. Typical HASM Hex File S1233000A60CB70A81B70C0F0BFDB60C8115001400811500140481AD3FAD7BCD309E27FB72 S1233020AD4CAD6CAD52AD5ACD0973AD5FCD098BCD09625A26F51500CC01800D0A5265736E S1233040756C74732066726F6D204D6F64652033206172653A0D0A00ADB8ADA4ADAFA690E7 S1233060ADA3A62BAD9FA6FFAD9BA6902097AD9DA692AD91A600208DAD93A692AD87A61090 S12330802083AD89A600CD3005AE0881CD300581AE005A26FD81CD300DA613CC3005CD3084 S10730A005A54081BD S9030000FC Listing File The listing file is one of the most useful files generated by HASM for the programmer to use when debugging software. The listing file is a plain ASCII text document that consists of the assembly source code merged line by line with the assembled machine code and other pertinent information like address location, variable values, cycle counts and more. HASM 3.0 User's Guide 11 2 Using HASM 3.0 Output File By default, a listing file is not created when a file is assembled with HASM. To instruct HASM to create a listing file, include the /L command line switch when invoking the assembler. The default name of the listing file created when the /L switch is included is source file name with the .LST extension appended. For example, of the name of the source file is myfile.asm, the name of the listing file will be myfile.lst. If a different extension is preferred, add the =ext directive to Example 4. Typical HASM listing file HARRIS Semiconductor (c)1990 - 1997 68HC05 Assembler Version 3.0.2 Filename: EX1.LST Source Created:07/28/97, 10:57 am Assembled: 07/28/97, 10:57 am 00001 * Above is the header information 00002 * 00003 #include ;including a file ------------------ START OF INCLUDE \6805\include\C16B.S ---------------00001 #nolist 00144 #list ------------------ END OF 00004 00005 00006 $00A1 = 161 00007 $0007 = 7 00008 00009 00010 0050 00011 0050 00012 0051 00013 00014 00015 0100 00016 00017 [2] 0100 9C 00018 [2] 0101 9B 00019* [3] 0102 2002 00020 00021 [3] 0104 20FE 00022 00023 [2] 0106 A6A1 00024 [4] 0108 B750 00025 [3] 010A B607 00026 [4] 010C B751 00027 [3] 010E 20F4 00028 00029 0110 562300 12 INCLUDE \6805\include\C16B.S ------------------ con1 con2 equ equ $A1 7 byte word section vars, $50 ds 1 ds 2 ;these are constant ;definitions ;these are memory ;reservations section code, $100 rsp sei jmp ;this is assembled code jumpHere bra * lda sta lda sta bra #con1 byte con2 word imback db $56, $23, 0 ;optimized, note the * imback jumpHere ;Byte assignment Using HASM 3.0 Output File the /L switch. As a result, if the file myfile.asm is assembled with the command line switch /L=lsf, the name of the listing file will be myfile.lsf. The =ext part of the /L switch is optional. The format of the HASM listing file is very simple. At the beginning of the file is a standard header that contains copyright information, the assembler version, the filename of the listing file, and the time and date when the source file was created and when it was assembled. Next the listing of the source code begins. The listing file is organized in a column format; different columns of the text indicate different items. The following is an example of a typical source line: 00020 Line Number [2] 0101 Cycle Count 9B Address Location sei Assembled Opcode Source In the first columns of each line contain the line number of the current file. This line number is nothing more than a simple indicator of position within the file and has nothing to do with the assembled code. For lines of assembled code, the cycle count is next. Contained between square brackets, this number indicates the number of 68HC05 CPU cycles required to execute the instruction. An "M" in the brackets indicates that a macro is being invoked. After the cycle count is the memory address where the instruction resides. Next comes the assembled machine code for the instruction in the source line. Finally, the source line is displayed in the same format as in the source file itself. Note: A asterik ( * ) after the line number indicates that particular line has been optimized. Source lines with constant definitions, macro expansions, comments, memory reservations, byte assignments and other "non-code" directives are displayed with all pertinent information in the listing file. Example 4 shows a typical HASM listing file. Error File When HASM encounters an error during assembly, it will abort the process and notify the user. By default, HASM prints all error and warning messages to the screen. However, if the /E command option is included, HASM will create an ASCII text file and write all of the errors and warnings there. If an error file is created, it is given the same base name as the source file with the .ERL extension. For example, of the name of the source file is myfile.asm, the name of the error file will be myfile.erl. If a different extension is preferred, add the =ext directive to the /E switch. Thus, if the file myfile.asm is assembled with the command line switch /E=err, the name of the error file will be myfile.err. The =ext part of the /E switch is optional. HASM 3.0 User's Guide 13 2 Using HASM 3.0 Output File Error messages in HASM are designed to tell the user the cause of the error, which file is was in and on what line the error occurred. The following is a typical error message: EXP1.S ( 17) ERROR: Illegal opcode/pragma: File with error Line number RSPS Error Message A listing of all HASM errors and warnings is included in Appendix A. Symbol File The symbol file is the last of the four file types generated by HASM. By default, no symbol file is generated when a source file is assembled. If the /S command option in included, however, HASM will create the file with the same base file name as the source file and the .SYM extension appended. The purpose of the symbol file is to provide a complete listing of all constants, variables and labels defined in the source file. While this file may not be of much use to the programmer, it is used by Harris development tools to allow for symbolic debugging of source code. Also, is a symbol file from one assembled program is included in another, the new program can make jumps to the labels defined in the assembled program and use all its variable definitions. A symbol file consists of a header and the symbol table. A typical symbol file is shown in Example 5. Example 5. Typical HASM Symbol File * * * * * * HARRIS Semiconductor (c)1990 - 1997 68HC05 Assembler Version 3.0.2 Filename: EX1.SYM Source created:07/28/97, 12:00 pm Assembled: 07/28/97, 12:00 pm Table of labels/symbols: ;LABEL/SYMBOL ;------------------------------------------------BYTE CODE CON1 CON2 IMBACK JUMPHERE VARS 14 equ equ equ equ equ equ equ Hex --- Decimal ------- $0050 $0100 $00A1 $0007 $0104 $0106 $0050 ;V ;V ;K ;K ;V ;V ;V 80 256 161 7 260 262 80 Using HASM 3.0 Output File HASM 3.0 User's Guide 15 2 16 Using HASM 3.0 Output File Source File Syntax 3 3 As stated in Chapter 2, the input to HASM is a standard text file. Control codes should be removed and if the file is generated with a word processor such as WordStar or WordPerfect, the file should be saved in TEXT or NON-DOCUMENT mode. NOTE: HASM is CASE INSENSITIVE in its interpretation of filenames, command line switches, symbols, labels, opcodes, and directives. The treatment of text other than comments depends on its position on a line. There can be up to five main types of information contained on each line in a source file. They are: * * * * * labels mnemonics mnemonic operands comments assembler directives (see Chapters 4-5) The first four types are described in this chapter. The last type, including assembler pragmas and macros, are explained in Chapters 4 and 5. Comments and Labels HASM observes syntax rules similar to many other assemblers. Comments can be freely placed in the input (source) file, provided that they are either: 1. are preceeded by a semicolon ( ; ), or 2. begin with an asterik ( * ) in the first column Comments demarcated with a semicolon can begin in any column. Additional formatting can be achieved with free use of blank lines. Tabs can also be used and are expanded to standard 8th column tab stops. Any string of characters which begins in first column on a line on a line is generally interpreted as a label or a symbol. There are a few exceptions to this rule -- the asterik ( * ) and semicolon ( ; ) comments already discussed and assembler prag- HASM 3.0 User's Guide 17 3 Source File Syntax Mnemonics mas. Pragmas are a set of predefined keywords, delimited with either a "#", a "$" or a "/" that give HASM special instructions on how to assemble the source file. These will be discussed in detail in the next chapter. Valid label names may begin with any letter of the alphabet, a question mark ( ? ), or an underscore ( _ ). Names cannot include arithmetic/logical operators ( + - * / & | ^ ~ ! < > = ), nor can they include a semicolon ( ; ), nor can they be a valid numeric expression (i.e. $AF). Labels are valid to 50 characters and are internally converted to uppercase - the label/symbol can be defined with upper and lower case characters freely mixed to improve readability, but two labels/symbols which differ only in case may cause errors (i.e. - RunFile and runfile will both be interpreted as the same item, if that's the intent, O.K.). If a colon is used during label definition it is interpreted as a label operator and not apart of the label itself. Example 6 shows the usage of comments and labels. Example 6. Using Comments and Labels ******************** ; So is this This is a comment ; and this is another comment, and the following ; blank line is fine Label_here Symbol_here EQU 8 ; this is a label, and a comment on the same line ; this is a symbol - a symbolic constant Mnemonics The first string (often referred to as tokens) which doesn't begin in column one and is not preceeded by a semicolon ( ; ) is interpreted as either a 68HC05 instruction mnemonic or as an assembler directive. Instruction mnemonics are directly translated into the proper hex value for execution by a 68HC05 processor. Assembler directives, on the other hand, do not generate instructions for the 68HC05 - instead they allow creation of constants (for use during assembly), affect the memory location where the opcodes are placed and assign memory address values to symbols (variables and constants). The next token on a line is assumed to be the argument to the instruction/directive. If the argument count is incorrect, an error is generated. Any number of spaces/tabs (at least one is required) are allowed between column one (or a label which begins in column one) and the instruction/directive. Similarly any number of spaces (at least one) are allowed between the instruction/ directive and its arguments. Following the arguments only comments preceeded with a semicolon ( ; ) 18 Source File Syntax Numbering Formats are allowed. Maximum line length is 200 characters! As with all HASM strings, mnemonics and directives are case insensitive. Example 7. Mnemonic and Argument Formatting Begin_here lda #225 sta 25 lda Lda LDA counter Counter COUNTER ; ; ; ; this is a label with a command and an argument a command plus argument without a label ; ; ; ; lower case and upper case can be mixed with no affect on interpretation. Use case to improve readability End_here rts ;this is an instruction which takes no arguments and is tough ;to read. A_good_one brclr 7,var,quit ; use white space to improve ; legibility !!! Numbering Formats The default base of HASM is 10 (decimal). To express numbers in other formats, delimiters are required. HASM is capable of interpreting decimal, binary, hexadecimal and character (ASCII) numbering formats. Delimiting the different bases is as follows: * Binary numbers must begin with either a "%", a "0B" or end with a "B" * Hexadecimal numbers must begin with a "$", a "0x" or end with an "H" * Characters must be enclosed in either single or double quotes. Table 2 shows a comparison and the usage of the valid numeric forms for each type. Table 2. Valid Numeric Forms in HASM Number (Decimal) Binary Hexadecimal Character 68 %1001000 $44 "D" 125 0B1111010 0x7D `z' 230 11100110B 0E6H HASM 3.0 User's Guide 19 3 Source File Syntax Expressions and Operators Expressions and Operators HASM supports arithmetic, logical and comparative expressions as arguments to opcodes and directives. Valid operators are shown in Table 3. Table 3. Arithmetic, Logical and Comparative Operators in HASM Symbol Function + addition and unary plus - subtraction and unary minus * multiplication / division ! exponentiation & bitwise AND | bitwise inclusive OR ^ bitwise exclusive OR ~ bitwise invert > greater than < less than = equal to Note that the result of a comparative expression (those including <, >, or =) is either "1" if the comparison is true or a "0" if it is false. Generally comparative operators are used only with "if" directives to control assembly. Arguments in the expressions can be labels/symbols, the special current location characters ( * or $ ), or any valid number. Valid labels/symbols formats have already been defined. Forward references of labels is permitted, but symbolic constants must be defined before being referenced. Arguments to the EQU directive cannot be forward references. IMPORTANT: No spaces are allowed in expressions. Parenthesis can be used for setting precedence. Intermediate results can reach 4M, but final results must meet the appropriate range of the instruction or directive. All numbers are considered decimal unless denoted by binary, hex or character operators 20 Source File Syntax Addressing Modes The minus sign ( - ) can be used as the first character of an expression (unary negate) to generate a negative result. Within an expression the minus sign requires both a left and a right operand. Example 8 shows some valid HASM arithmetic, logical and comparative expressions. Example 8. Valid Expressions Konstant EQU ((`F'-'A')*16+(5*(3-2)/2)*0xffff)&0xffff Hi_byte Lo_byte lda ldx label/256 label&255 ;convenient expressions for splitting ;an address to upper/lower bytes bra * ;an endless loop bra 2** ;first star is a multiply op the 2nd ;is the current program location ora #2!3 ;set bit 3 of A (Note: 2!3 == $08) ;tests is current location is $100 lda #$20 and -3*(0-8) #if *=$100 #endif ;valid use of `-' #if *>$1F00 #error "Out of memory" #endif ;comparative expression to test current ;memory location Addressing Modes The addressing mode for most 68HC05 instructions can be selected by the user through programming. HASM determines the intended address mode based on the argument type or magnitude. The valid address modes are as follows. Inherent In the inherent addressing mode, all of the information needed for instruction execution is inherently known to the CPU. The only operands available for inherent instructions are CPU registers (accumulator, index, stack pointer, condition code). This type of addressing is determined by the mnemonic. Example of an inherent addressing instruction: 00031 [2] 0113 HASM 3.0 User's Guide 9C rsp 21 3 Source File Syntax Addressing Modes Immediate In the immediate addressing mode, the operand is a data byte contained in the program memory immediately following the opcode. This type of addressing is used when the working with constant values that are known at assembly time. Immediate operands are denoted by placing a "#" in front of them. Only integers in the range of -127 to +255 ($00 to $FF) are valid operands for immediate addressing. NOTE: One common problem with programmers who are new to 68HC05 assembly code is omitting the "#" in an immediate instruction. The instruction lda #$55 will put the value $55 into the accumulator. The instruction lda $55 will put the value in memory location $55 into the accumulator. Example of an immediate addressing instruction: 00032 [2] 0114 A626 lda #$26 Extended In the extended addressing mode, the address of the operand is contained in the two bytes of program memory immediately following the opcode. With this mode, any memory in the 68HC05 address space is addressable, including RAM, ROM and I/O. Valid operands are integers in the range of -32768 to +65535 ($0000 to $FFFF). The instruction lda $1025 is an extended addressing instruction. Example of an extended addressing instruction: 00034 [4] 0118 C61223 lda $1223 Direct The direct addressing mode is a space and time saving version of the extended addressing mode. In the direct mode, the upper byte of the operand address is assumed to be $00, thus allowing direct addressing only access to Page 0 (memory locations from $00 to $FF). Direct mode instructions are one byte shorter than extend mode ones and execute in one CPU cycle less. Since all of the main I/O and RAM (these are the most frequently addressed parts of the 68HC05 memory) this addressing mode can result in quite a time and code savings. Some instructions, are direct mode instruction only. These are the bit manipulation opcode (BRSET, BRCLR, BSET, and BCLR). They have no extended addressing counterpart. Example of an extended addressing instruction: 00033 22 [3] 0116 B626 lda $26. Source File Syntax Addressing Modes NOTE: If the operand of a memory addressing instruction is a variable, HASM will calculate the value of the variable and use the appropriate addressing mode. However, if the variable is forward referenced, HASM does not know its value at assemble time and therefore reserve the most space available -- two bytes -and thus uses extended addressing. Once the variable value is know, HASM goes back and fills the value in. If the variable is a Page 0 reference, the upper byte is filled with $00 and extended addressing is used. An exception to this is when optimization is turned on. Then HASM knows all variable values before assembly and will always use the correct addressing mode. See Chapter 6 for more details on optimization. Indexed In indexed addressing, the address of the operand is calculated by the CPU by adding the value in the X register (i.e. the index register) with the immediate operand(s) following the opcode in program memory, refer to as the offset. Up to two bytes may be included as an offset, and as a result there are three types of indexed addressing available in the 68HC05 architecture. Indexed, no offset If no offset is specified then the effective offset is $00. Thus, the operand of the instruction is simply the value in the X register. This type of addressing can only access the lower 256 bytes of 68HC05 memory, or Page 0. Note that there are two standard ways of writing the indexed, no offset mnemonic in 68HC05 assembly source code. The first way is to simply include "x" as the argument to a valid indexed opcode. The second method is similar except that a comma is placed before the "x". HASM supports both styles and assembles them identically. Examples of indexed, no offset, addressing: 00035 00036 [3] 011B [3] 011C F6 F6 lda lda x ,x Indexed, 1 byte offset This indexed mode includes on immediate byte after the opcode in program memory as the offset to the value in the X register. The offset and X register are added together to get the address of the operand. This type of addressing can access memory from $0000 to $01FE. Example of indexed, 1 byte offset, addressing: 00037 [4] 011D HASM 3.0 User's Guide E633 lda $33,x 23 3 Source File Syntax Addressing Modes Indexed, 2 byte offset Indexed, 2 byte offset, addressing works similar to indexed, 1 byte offset except that the two bytes immediately following the opcode are used as the offset. This type of addressing can access memory from $0000 to $FFFF. Example of indexed, 2 byte addressing: 00038 [5] 011F D61223 lda $1223,x NOTE: Similar to the situation with direct and extended addressing modes, when a variable is used as the offset to an indexed addressing instruction, HASM will calculate the value of the variable and use the appropriate mode. If that label is a forward reference, HASM will reserve the maximum amount of space necessary and will always use indexed, two byte offset addressing. However, if optimization is on the correct mode will always be chosen since the label values are known at the time of assembly. See Chapter 6 for more details. Relative The relative branch instruction is only used for branch instructions. Most branch instructions are two byte opcodes (bit test and branch instructions are contain three bytes) -- the first byte is the opcode byte and the second byte is the relative branch offset. This offset is a twos-compliment signed byte and is added to the program counter to calculate the branch address. For example, if the offset is $F0, the program will branch 16 location backwards. Since the offset is a signed byte, the result is that branch instructions can jump 128 location backward and 127 locations forward. All branch locations in 68HC05 source code require the address of location to jump to. This address is almost always given in the form of a label. HASM calculates the relative branch offset from the address and will generate an error if the jump location is beyond the -128 to 127 location range allowed by relative branch instructions. Example of relative branch addressing: 00037 [3] 011D 2EE6 bil location Bit test and branch Bit test and branch instructions address memory locations through direct addressing (and as such can only test bits on page zero ($00-$FF) and branch using relative addressing. These instructions are generally classified under direct addressing. 24 Source File Syntax Supported Opcodes Example of bit test and branch (direct) addressing: 00037 [5] 011D 060120 brset 3,portb,location Supported Opcodes All standard 68HC05 opcodes are supported by HASM. Opcodes exclusive to 68HC05 clone MCUs, like the decimal adjust accumulator instruction, are not supported. HASM 3.0 User's Guide 25 3 26 Source File Syntax Supported Opcodes Assembler Directives 4 4 Assembler directives are instructions included in the source code that are not translated directly into machine code for the 68HC05. Instead, HASM interprets these directives and assembles the source file accordingly. These instructions control data allocation, conditional code assembly, and can generate user defined errors. There are three main types of assembler directives that are recognized by HASM: * data allocation directives * assembler control directives (often referred to as pragmas) * macro directives This chapter discusses the use of the data allocation directives and the assembler control pragmas. Macro directives are discussed in Chapter 5. Data Allocation Directives Data allocation directives control the way HASM assembles the source code into the 68HC05 memory map. These directives can reserve memory space, define data bytes, and start the code assembly at a specific address. NOTE: values in curly braces ( { and } ) in the list below contain descriptive text for the syntax description. Curly braces are not used in HASM and sould not appear as apart of these directives. .ascii Syntax: .ascii .ascii "{ascii string}" '{ascii string}' HASM 3.0 User's Guide 27 4 Assembler Directives Data Allocation Directives Description: The .ASCII directive is used to define ASCII text strings in memory. The text string is located in memory at the current address where the .ASCII directive is encountered by HASM. The argument to the .ASCII directive is a text string delimited with either single or double quotes. See also: DB, HEX, .BYTE, and FCB Example: label .ASCII .ASCII "Double Quotes" 'Single Quotes' boolean See ds. byte See ds. .byte See db. char See ds. db Syntax: db hex .byte fcb {byte}, [{byte}, {byte} ... ] {byte} [{byte} {byte} ... ] {byte}, [{byte}, {byte} ... ] {byte} [{byte} {byte} ... ] Description: DB, HEX, .BYTE, and FCB are all synonyms for allocating and initializing memory locations, in byte sized portions. If no argument is given, a single byte is allocated but not initialized. (This make the directives equivalent to a ds 1 28 Assembler Directives Data Allocation Directives directive). A series of arguments can be given, provided each argument equates to a byte (range $00 to $FF) or is an ASCII string. Arguments can be separated by space(s) or commas or a comma followed by space(s). The directive must begin after column 1. Examples: label db hex fcb .byte label2 $20, 2;two bytes defined 'X' 'Z' 'S' $55 "Another string" $20 %110100 ds Syntax: ds rmb byte char integer boolean {value} {value} {value} {value} {value} {value} Description: The ds directive is one of a set of six interchangeable directives (RMB, BYTE, CHAR, INTEGER, and BOOLEAN are the others) whose purpose is to reserve memory in single byte increments. Like mnemonics, these directives require an argument that defines the total number of data bytes to reserve. Note that no value is assigned to the reserved memory. Labels can be included with these directives and are assigned the value of the first byte allocated by the directive. These are generally used allocating RAM space. Examples: label ds rmb byte 2 1 5 ;two byte variable "label" ;no label but 1 byte is still reserved ;5 bytes defined label2 integer 10 ;10 byte array boolean 80 ;80 byte array HASM 3.0 User's Guide 29 4 Assembler Directives Data Allocation Directives dw Syntax: dw fdb .word {word}, [{word}, {word} ... ] {word}, [{word}, {word} ... ] {word} [{word} {word} ... ] Description: DW, FDB, and .WORD are all synonyms for allocating and initializing memory locations in word (16 bit) sized portions. These directive work similar to the DB, HEX, .BYTE, and FCB directives. If no argument is given, two bytes are allocated but not initialized. A series of arguments can be given, provided each argument equates to a word (range $0000 to $FFFF). Arguments can be separated by space(s) or commas or a comma followed by space(s). The directive must begin after column 1. Examples: label dw fdb .word $2022 $155, $00, $1 "Yet Another string" ;1 word defined ;3 words defined end Syntax: end Description: The END statement is used to define the end of a block of source code. HASM will ignore all text from the END statement until the end of the current file. Example: section vectors, $1FF8 dw dw dw dw end 30 timer_vector irq_vector swi_vector reset_vector Assembler Directives Data Allocation Directives equ Syntax: {label} equ {value} Description: The EQU statement is used to define constant values for use in the source file. EQU takes two arguments -- a valid label name before the directive (and beginning in column one) and a number or numerical expression after the directive. When assembling the source file, HASM replaces all occurrences of the label with the value assigned to it. Constants defined with the EQU statement can be used as arguments to opcodes, in "IF" statements and anywhere else a numerical expression is accepted. Numerical arguments of the EQU statement CANNOT be forward references. Examples: label label2 equ equ $34 label ;label = $34 ;valid; label2 = label1 = $34 fcb See db. fdb See dw. hex See db. integer See ds. org Syntax: org {16 bit value} HASM 3.0 User's Guide 31 4 Assembler Directives Data Allocation Directives Description: ORG sets the current program location; the following instructions and data are compiled into memory beginning with that location. ORG must begin after the first column. Valid arguments for ORG are integers between $0000 and $FFFF. See also: SECTION Examples: org org $100 start ;program location set to $100 ;program location defined by "start" rmb See ds. rmw Syntax: rmw word {value} {value} Description: The RMW directive is one of a set of directives (along with WORD) whose purpose is to reserve memory in single word increments. Like mnemonics, these directives require an argument that defines the total number of data bytes to reserve. Note that no value is assigned to the reserved memory. Labels can be included with these directives and are assigned the value of the first word allocated by the directive. These are generally used allocating RAM space. Examples: label rmw word 3 1 ;three word (six byte) variable "label" ;no label but 2 bytes are still reserved section Syntax: section {label}, {16 bit value} 32 Assembler Directives Control Pragmas Description: The SECTION directive is very similar to the ORG statement in that it is used to set the current program location. SECTION, however, takes two arguments -- a label and the new program location. In this way sections of code can easily be defined with a label and location in one statement. The SECTION directive must begin after column one. See also: org Example: section code, $100 ;code = $100 .word See dw. word See rmw. Control Pragmas Control directives, or pragmas, are used to control the way HASM assembles the source code. All valid assembler pragmas begin with a pragma delimiter -- either a "#", a "$" or a "/". These symbols can be used interchangeably. For the examples shown below, the "#" is used. The "$" or the "/" could be substituted for the same effect. IMPORTANT: All pragmas MUST begin in column 1. Pragmas in any other column will be considered errors. All pragmas MUST begin with a pragma delimiter. The following are all valid HASM 3.0 assembler pragmas. else Syntax: #else HASM 3.0 User's Guide 33 4 Assembler Directives Control Pragmas #elseif Description: ELSE and ELSEIF are used in conjunction with the IF pragma to provide alternative events in the case the IF evaluates false (or, true in the case of the IFNOT directive). These pragmas are interpreted identically by HASM and can be used interchangeably. The ELSE statement must come after either an IF or IFNOT statement. Unlike the IF and IFNOT pragmas, ELSE and ELSEIF do NOT evaluate an expression and do not require arguments. As a result, there can be only one ELSE statement in a IF-ENDIF block. See also: if, ifnot, elseif, endif Example: #if *>$100 org #else org #endif #if label org #elseif org #endif $200 ;if current location > $100 ;start new block at $200 $100 ;else start new block at $100 ;use label to control assembly $1000 $2000 NOTE: Note: the ELSEIF pragma is included in HASM for compatibility with other assemblers. Its name would imply that it, too, evaluates arguments like the IF statements. This can be confusing, especially to those new at 68HC05 programming. Our suggestion is to stick to the use of the ELSE statement. elseif See else. endif Syntax: #endif 34 Assembler Directives Control Pragmas Description: The ENDIF pragma is used to mark the end of a conditional assembly IF block. Every IF and IFNOT statement must be accompanied by a closing ENDIF to define the conditional block. See also: if, ifnot, else, esleif Example: #if *>$100 org #endif $200 ;if current location > $100 ;start new block at $200 endmacro Syntax: #endmacro Description: The ENDMACRO pragma is used to indicate the end of a macro definition. Refer to Chapter 5 for deatils on using macros. endrepeat Syntax: #endrepeat Description: ENDREPEAT marks the end of a repeated block of code. See REPEAT for more details. See also: repeat error Syntax: #error "{error message}" HASM 3.0 User's Guide 35 4 Assembler Directives Control Pragmas Description: The ERROR pragma is used to cause HASM to abort assembly. When the assembly is aborted, the error message is displayed in the error output. Generally this pragma would be used with a IF statement to guard against certain conditions occurring during assembly. Example: #if *>$1EFF ;$1EFF is upper limit of ROM #error "Out of ROM!" #endif if Syntax: #if {expression} Description: The IF statement begins a block of conditionally assembled code. The IF directive evaluates the expression and, if "true", assembles the source code between the IF and a matching ELSE, ELSEIF or ENDIF pragma. In HASM, an expression is considered "true" if it exists and evaluates to a non-zero number. Likewise, an expression is "false" if it does not exist or evaluates to zero. Any block of condition assembly code, beginning with an IF pragma, MUST be terminated with an ENDIF statement. IF statements can be nested within other IF statements up to 20 levels deep. DO NOT USE FORWARD REFERENCES. If a forward reference is used it will evaluate as false the first pass and as true on successive passes. See also: else, elseif, endif, ifnot Example: test1 test2 equ equ #if test1 db #else #if test2 db 36 0 1 ;1st IF level, this one is false "This part will not be assembled" ;else for 1st level IF ;nested 2nd level IF "This part will be assembled" Assembler Directives Control Pragmas #endif #endif ;endif for 2nd level IF ;endif for 1st level IF ifnot Syntax: #ifnot {expression} #if not {expression} or Description: The IFNOT pragma works in the same way as the IF statement, except that it has the effect of negating the result of the evaluated expression. Thus, if the expression evaluated is "false" (i.e. undefined or zero), the code between the IFNOT and matching ELSE or ENDIF will be assembled. If there is an ELSE statement after an IFNOT that evaluated to "false", the code between the ELSE and ENDIF will be not assembled. Conversely, if the IFNOT evaluates to "true", the following code up to a ELSE or ENDIF will not be assembled. The pragmas IFNOT and IF NOT are equivalent and may be used interchangeably. HASM evaluates IFNOT and IF statements in a similar fashions; as such they may be nested within each other up to 20 levels deep. As with IF statements, DO NOT USE FORWARD REFERENCES. See also: if, else, elseif, endif Example: test1 test2 test3 equ equ equ 1 1 0 #ifnot test1 db "This will not be assembled" #else #if not test3 #if test2 db "This will be assembled" #endif #elseif db "This will not" #endif #endif HASM 3.0 User's Guide 37 4 Assembler Directives Control Pragmas include Syntax: #include{filename} #include "{filename}" #include '{filename}' #include Description: The INCLUDE pragma allows the insertion the contents of one source file into a second file. The argument of the INCLUDE directive should be a valid DOS path\filename for the file to be included. If single, double, or no quotes are used around the filename, HASM searches the current working directory or the path specified (including drive letters) for the file. However, if the filename is surrounded by angle brackets ( < and > ), HASM searches the standard include path as specified by the /I=path command line switch. See Chapter 2 for more information on the standard search path. Examples: (Note: Source assembled with the switch: /i=C:\6805\ ) #include ;this searches for C:\6805\, the ;standard path set by the /i switch #include "\path\file";this searches the path beginning at ;the root directory (DOS construct) #include 'file' ;this searches the current working ;directory #include path\file ;this searches the path specified list Syntax: #list Description: The LIST pragma has the function of enabling the output to the listing file. This command is often used with the NOLIST function to "hide" blocks of code from being displayed in the listing file. See also: nolist 38 Assembler Directives Control Pragmas Example: #nolist db db #list "This code is assembled but not shown" "in the listing file" macro Syntax: #macro {label} Description: The MACRO pragma is used to indicate the beginning of a macro definition. Refer to Chapter 5 for deatils on using macros. macroend Syntax: #macroend Description: The MACROEND pragma is used to indicate the end of a macro definition. Refer to Chapter 5 for deatils on using macros. nolist Syntax: #nolist Description: The NOLIST pragma is used to disable the output to the listing file. The command is often used with the list directive to "hide" blocks of code. See also: LIST HASM 3.0 User's Guide 39 4 Assembler Directives Control Pragmas noopt Syntax: #noopt Description: The NOOPT pragma is used to disable optimization of the source code from that point on. See Chapter 6 for more details. See also: OPT opt Syntax: #opt Description: The OPT pragma is used to enable optimization of the source code from that point on. See Chapter 6 for more details. See also: NOOPT page Syntax: #page Description: PAGE is used to insert a form-feed character in the listing file. repeat Syntax: #repeat {value} 40 Assembler Directives Control Pragmas Description: REPEAT allows a section of code to be repeated multiple times. The source code between the repeat and matching ENDREPEAT are assembled as many times as defined by {value}. Each REPEAT section of code requires a closing ENDREPEAT. This directive is most commonly used to fill unused portions of memory with NOP or SWI instructions. When filling with NOPs the last several open locations are commonly used for a JMP Begin, where Begin is the label for the program start. Note that listing files only contain one copy of the repeated code to conserve space. If a complete listing is desired add a list statement as the first line in the repeated block. See also: ENDREPEAT Example: ; This code will fill the rest of memory (to $1F00) with ; SWI instructions #repeat $1F00-* swi #endrepeat set Syntax: #set {label} Description: The SET pragma is used to set a label or variable to a known, "true" state. This label will evaluate to "true" in all IF and IFNOT statements. Typically, the label is assigned the number 1, but since "true" is defined as any non-zero number, this should not be used to define as a constant as 1. This pragma is typically used only in setting up conditional assembly variables at the beginning of a source file. See also: SETNOT HASM 3.0 User's Guide 41 4 Assembler Directives Control Pragmas Example: #set test1 #if test1 db #elseif db #endif "This will be assembled" "This will not" setnot Syntax: #setnot {label} Description: The SETNOT pragma is used to set a label or variable to a known, "false" state. This label will evaluate to "false" in all IF and IFNOT statements. Essentially, the label is assigned the number 0. This pragma is typically used only in setting up conditional assembly variables at the beginning of a source file. See also: SET Example: #setnot test1 #ifnot test1 db "This will be assembled" #elseif db "This will not" #endif 42 User Defined Macros 5 5 What is a Macro? Macros are sets of directives and assembly instructions that are directly inserted into the source code when they are invoked. Macros have many advantages -simplified debugging, reduction of code writing for recursive routines, and a higher level of abstraction improves code readibility and understanding. Also, parameters can be passed to macros, making them even more flexible. Defining a Macro A macro is simply a collection of source code that is inserted into the source file whenever the macro is invoked. Unlike subroutines which are defined in the source program and called by the 68HC05, macros are evaluated by the assembler ONLY. The machine code is generated as if the contents of the macro were typed into the source file everywhere the macro label is found. Before macros can be invoked in the source code, however, they must first be defined. Forward referencing of macros is not allowed. Macros are defined using the #macro, #macroend, and #endmacro directives. The #macro and #endmacro (Note: #endmacro and #macroend are interpreted the same by the assembler and can be used interchangeably) pragmas are used to define macros within the source file. The macro definition pragma #macro takes the name of the macro as an argument. Whenever a macro is being defined, HASM will not assemble the source code between the #macro and #endmacro pragmas. The syntax of macro definitions follows: #macro {label} {macro source code goes here} #endmacro ;#macroend can also be used To invoke a defined macro in the source code, simply place the macro name in the source as if it were a mnemonic. This will cause HASM to start the expansion of the macro. The expanded macro is exactly what was defined in the macro definition, comments and all, except everything has been converted to uppercase. See Example 9. HASM 3.0 User's Guide 43 5 User Defined Macros Labels and Comments in Macros Example 9. Defining and Invoking a Simple Macro in HASM 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 #macro testmac lda #$FF ;make a simple delay loop deca bne loop1 ;this label is local loop1 #endmacro 0100 [2] 0100 [2] 0101 [M] 0102 section code, $100 9C 9B >> expanding macro TESTMAC ( ) 00001 00002 [2] 0102 A6FF 00003 LOOP1 00004 [3] 0104 4A 00005 [3] 0105 26FD 00006 >> end of macro TESTMAC 00015 ;define a macro called "testmac" [3] 0107 20FE rsp sei testmac ;invoke macro LDA #$FF ;MAKE A SIMPLE DELAY LOOP DECA BNE LOOP1 ;THIS LABEL IS LOCAL bra * ;loop forever Note the "M" in the cycle count brackets on the source line where the macro is invoked. This indicates that HASM has recognized the macro and is expanding it. NOTE: If you use a lot of macros and are confident that the function properly, HASM can be directed to turn of macro expansion in the listing file to "clean up" the code. To do this, include the /M command line switch when HASM is called. When HASM encounters a macro, the code will still be expanded and assembled, however all that will appear in the listing file is line where the macro was invoked. Labels and Comments in Macros Labels are allowed to be defined and referenced within macros. Label names that are defined within macros are appended with an "_n" suffix by HASM, where n is an incremental decimal value. In this way the assembler can make sure all labels within macros remain local to that macro and unique within the source file. The source code outside of a macro can NOT jump to any label within a macro. On the 44 User Defined Macros Labels and Comments in Macros other hand, jumps can be made from within a macro to labels outside the macro (also, jumps can NOT be made to labels inside other macros). It should be noted that when HASM encounters a label reference within a macro, it checks to see if the label is "global" (i.e. defined outside the macro) before it looks for the label within the macro definition. If a label is both global and local to a macro definition, HASM will "shadow" the local macro label with the global label. Thus, if there is a label in a macro called "jumpto" and a label outside the macro called "jumpto", all references to "jumpto" will refer to the label outside the macro. This is, of course, bad form and should be avoided. HASM will generate a warning if this condition occurs. Refer to Example 10 for details. Example 10. Global and Local Variables in Macros 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 #macro testmac loop2 lda #$FF ;make a simple delay loop deca bne jmp loop1 loop2 ;this label is local ;will jump to global label loop1 #endmacro 0100 [2] 0100 [2] 0101 [M] 0102 section code, $100 9C 9B rsp sei testmac >> expanding macro TESTMAC ( ) 00001 00002 LOOP2 00003 [2] 0102 A6FF 00004 LOOP1 00005 [3] 0104 4A 00006 [3] 0105 26FD 00007 [3] 0107 CC010A 00008 >> end of macro TESTMAC 00017 00018 ;define a macro called "testmac" ;invoke macro LDA #$FF ;MAKE A SIMPLE DELAY LOOP DECA BNE JMP LOOP1 LOOP2 ;THIS LABEL IS LOCAL ;WILL JUMP TO GLOBAL LABEL bra * ;define global label ;loop forever loop2 [3] 010A 20FE Note that in this example there are two branches in the macro testmac -- one to LOOP1 and one to LOOP2. Since the label LOOP1 in not define outside the macro, this branch will always jump to the LOOP1 inside the CURRENT expansion of that macro. However, since LOOP2 is defined outside the macro (on line 00017 at loca- HASM 3.0 User's Guide 45 5 User Defined Macros Passing Arguments to Macros tion $010A) as well as inside (on line 00004 at location $0102), all jumps to LOOP2 will refer to the global label LOOP2 at $10A. As seen in the Examples 9 and 10, comments may be included with the macro and are expanded in the listing file (if the /M switch is not used) each time the macro is invoked. The only change in the comments is that they are converted to uppercase like the rest of the text in the macro. NOTE: When a macro is defined, all text (including comments) within that macro is copied into memory for later expansion. Keep this in mind if your PC is short on memory or you use many and/or large macros. Passing Arguments to Macros Arguments may be passed to a macro when calling it. These arguments are referenced within the macro definition by the "%" character followed by the argument number (See Example 11). HASM will generate an error if too few arguments are passed to the macro; extra arguments are ignored. In Example 11, two parameters are passed to the macro - $FF and $50. Note that these values are shown in the heading of the macro expansion. HASM does not directly substitute the macro reference test (i.e %1, %2, etc.) with the parameter passed. Instead the references are treated as labels with the passed values assigned to them. Thus, the parameter references within the macro are not replaced with the parameters themselves. However, if you look at line 00001 of the macro expansion, you can see the opcode LDA #%1 was assembled as A6FF, indicative that the parameter was passed correctly. Since parameter references are treated as labels in macro expansions, they follow the same syntax rules as labels and can be used in mathematical expressions. Finally, note that the "%" operator is also the binary radix operator. Outside a macro tokens such as %1 and %10 will evaluate to the decimal numbers 1 and 2, respectively. In a macro, however, %1 and %10 may represent parameters passed when invoking the macro. When assembling macros, HASM gives the "%" operator priority as a macro parameter over a binary radix delimiter. For example, if assembling a macro HASM reads a #%10, it will check to see if there were ten parameters passed to the macro. If there were, %10 will evaluate to be the tenth parameter passed. If fewer than ten parameters were passed, %10 will evaluate to a decimal 2. 46 User Defined Macros Nested and Recursive Macros Example 11. Passing Arguments to Macros 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 #macro testmac ;define a macro called "testmac" lda #%1 ;make a simple delay loop using ;the 1st passed parameter deca bne lda loop1 #%2 ;this label is local ;return with A=2nd parameter loop1 #endmacro 0100 [2] 0100 [2] 0101 [M] 0102 section code, $100 9C 9B rsp sei testmac $FF, $50 >> expanding macro TESTMAC ( $FF[255] $50[80] ) 00001 00002 [2] 0102 A6FF LDA #%1 00003 LOOP1 00004 [3] 0104 4A DECA 00005 [3] 0105 26FD BNE LOOP1 00006 [2] 0107 A650 LDA #%2 00007 >> end of macro TESTMAC 00016 [3] 0109 20FE bra * ;invoke macro ;MAKE A SIMPLE DELAY LOOP USING ;THE 1ST PASSED PARAMETER ;THIS LABEL IS LOCAL ;RETURN WITH A=2ND PARAMETER ;loop forever Nested and Recursive Macros HASM 3.0 does not support nested or recursive macros. No macro may be invoked in the definition of another macro. HASM 3.0 User's Guide 47 5 48 User Defined Macros Nested and Recursive Macros Optimization 6 6 HASM 3.0 includes a new optimization features to help the programmer reduce code by substituting functionally identical 68HC05 opcodes for those instructions that take up more memory. Optimized Assembly Language? Assembly code, by nature, is the most efficient method of software programming. Since all 68HC05 mnemonics are mapped to machine code 1:1, there is not much room for optimization. However, there are some cases when certain instructions could be substituted with smaller (in terms of opcode bytes), functionally equivalent ones. This is the case with following instances: * indexed addressing with a zero offset * extended jumps to locations within -128 and 127 locations of the current program counter * extended subroutine calls to locations within -128 and 127 locations of the current program counter If optimization is enabled, HASM will search for these conditions and make the necessary changes. Enabling Optimization Optimization is turned on when assembling a source file with HASM by using the /O command line switch or whenever HASM encounters the #OPT pragma in the source file. If on, optimization may be turned off by the #NOOPT pragma. How Optimization is Done Like most mnemonic assemblers, HASM 3.0 is a two pass assembler. In the first pass HASM calculates all program locations and variable values. In the second pass the source code is assembled with these variables. However, when optimization is on, HASM recursively assembles the source code as many times as needed to compress all instruction capable of being optimized. While optimization can save many bytes of ROM in a large program, it does have the drawback that HASM 3.0 User's Guide 49 6 Optimization How Optimization is Done the extra assembly passes required by optimization increase the total assembly time. NOTE: HASM will indicate that a line has been optimized in the listing file by placing an asterik ( * ) after the source file line number on the line where the optimization occurred. See Example 10 for details. Optimization of Indexed Addressing Indexed addressing is the method of using the X register of the 68HC05 to access data in memory (see Chapter 3). This type of addressing is especially useful for transferring data to and from tables in memory. If offsets are supplied with an indexed instruction, the 68HC05 adds the offset value to the X register and uses the result for the memory access. The offset for these instructions can be $00. If it is, the one and two byte offset instructions will execute in the same way as a no offset instruction. With optimization on, HASM will evaluate the offset of an indexed instruction and substitute the indexed, no offset opcode if it evaluates to $00. Example 10 shows the same bit of code assembled with and without optimization. Example 12. Indexed Addressing Optimization 00001 $0000 = 00002 00003 0100 00004 00005 00006 [4] 0100 00007 [5] 0102 00008 00009 00010* [3] 0105 00011* [3] 0106 00012 00013 $0000 = 0 label equ 0 org $100 #noopt E600 D60000 lda lda label,x fwdref,x ;optimization off ;these instructions are not ;optimized lda lda label,x fwdref,x ;optimization on ;these instructions are ;optimized equ 0 #opt F6 F6 0 fwdref As shown in this example, the two load accumulator (LDA) instructions in the nonoptimized section of code require more ROM bytes than necessary. On line 00006, the opcode is assembled as the indexed, one byte offset instruction E600. On line 00007, since the label fwdref is a forward reference, the opcode is assembled as the indexed, two byte offset instruction D60000. The same instructions, however, in the optimized section of code have been replaced with the indexed, no offset instruction F6 in both cases. Here optimization saved 3 bytes of 50 Optimization How Optimization is Done ROM. Savings like this can be significant especially when working with 68HC05 devices with small ROM sizes like the CDP68HC05P1B. Note the optimization asteriks on lines 00010 and 00011. Optimization of Extended Jumps/Subroutine Calls Another way HASM can optimize 68HC05 code is in the area of program jumps and subroutine calls. The 68HC05 has two methods of changing the current program location: relative branches and direct jumps. With relative branches, a one byte, signed twos compliment number is added to the current program counter to get the new program location. As a result, the 68HC05 can jump -128 locations backward and 127 locations forward. In direct jump instructions, the address of the new program location is contained in two bytes following the opcode (the 68HC05 architecture has a maximum address space of 64kB). This two byte address is loaded into the program counter and the jump is made. Relative branch instructions use two bytes of memory; direct jump instructions use three. If a direct jump is made to a location within -128 or +127 locations of the current program counter, that direct jump can be replaced with a relative branch. If optimization is on and a direct JMP or JSR instruction is encountered, HASM will calculate the range of the jump and, if they are within the relative branch range, substitute the relative branch opcode instead. Note, however, that HASM does not convert relative branch instructions (BRA and BSR) to direct jumps instructions. If a branch location is encountered that is out of range, an error is generated. Optimization of JMPs and JSRs is shown below in Examples 13 and 14. Example 13. Optimization of Extended JMPs and JSRs - Non-optimized code 00001 00002 00003 00004 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016 0100 section code, $100 [2] 0100 [6] 0102 [3] 0105 A6FF CD0108 CC0400 lda jsr jmp #$FF delay toofar [3] 0108 [3] 0109 [6] 010B 4A 26FD 81 deca bne rts delay 0400 [2] 0400 [6] 0402 [3] 0405 A6F5 CD0108 CC0400 section lda jsr jmp toofar, $400 #$F5 delay toofar delay ;JSR in close range ;JMP > 127 forward ;delay subroutine HASM 3.0 User's Guide ;JSR > 128 backward ;JMP in close range 51 6 Optimization How Optimization is Done Example 14. Optimization of Extended JMPs and JSRs - Optimized code 00001 00002 00003 00004* 00005 00006 00007 00008 00009 00010 00011 00012 00013 00014 00015 00016* 0100 section code, $100 [2] 0100 [6] 0102 [3] 0104 A6FF AD03 CC0400 lda jsr jmp #$FF delay toofar [3] 0107 [3] 0108 [6] 010A 4A 26FD 81 deca bne rts delay 0400 [2] 0400 [6] 0402 [3] 0405 A6F5 CD0107 20F9 section lda jsr jmp toofar, $400 #$F5 delay toofar delay ;JSR in close range ;JMP > 127 forward ;delay subroutine ;JSR > 128 backward ;JMP in close range In these two examples, the same sections of code were assembled with optimization off (Example 11) and on (Example 12). The effects of optimization can be seen on lines 00004 and 00016 of the listing file. In Example 11, these branch instruction were within the "relative brach" range of the 68HC05, i.e. within 127 locations forward and 128 location backward. In Example 11, HASM assembled the mnemonic exactly as shown -- JSR DELAY was assembled as CD0108 and JMP TOOFAR was assembled as CC0400. However, in the optimized code, these HASM assembled these instructions as if they were written as BSR DELAY (AD03) and BRA TOOFAR (20F9), thus saving two bytes of ROM. Note the optimization asteriks. 52 Errors and Warnings A A Appendix This chapter contains a listing and explanation of the error and warning message generated by HASM 3.0. These errors will either be printed on the screen during assembly or, if the /E command switch has been used, written to an error file. Error and warning messages do not appear in the listing file. NOTE: HASM starts the generation of a listing and hex file on the FINAL pass of assembly. If HASM finds errors in the source file before the final pass, new listing and hex files will not be generated. Error Messages Error messages are generated whenever HASM encounters a condition in the source file that makes complete assembly of the file impossible. HASM will abort assembly upon the detection of such errors. {Expression} is not on page zero The 68HC05 bit operations (BSET, BCLR, BRSET, BRCLR) all require operands that are memory addresses located on page zero (addresses $00 - $FF). This commonly occurs when trying to modify or test RAM locations that are above memory location $FF. Branch location out of range You are trying to make a relative branch to a program location outside of the -128 to 127 locations allowed. If the cause of the error is a BRA or BSR opcode, replace with JMP or JSR instructions, respectively. For other relative branch instructions, the code needs to be rewritten to bring the location within range. This error will also occur if a branch is made to a label that has not been defined. Can't allocate space to store label {label} HASM has used all of the free memory available in the PC. Try closing unused programs and reassembling. Manual Title A-1 A Errors and Warnings Error Messages Can't open {filename} HASM can not open the specified file. Check to see if the file is being used by another program. Duplicate label name: {label} You have used the same label name at two different location in the source file. Labels in HASM cannot be redefined and must be unique within the source code. Duplicate macro name: {label} You have defined two macros with the same name. All macros must be assigned a unique macro name; these names must not duplicate labels and variable names. Duplicate section name: {label} You have tried to redefine a section name with a label that already exists. Section names, like labels, must be unique. Error in switch You have supplied HASM with either an invalid or duplicate command line switch. Valid switches are listed in Appendix B. #EQU statement has changed values during optimization You have tried to redefine a constant during optimization. While HASM will allow the redefinition of constants during normal assembly, during optimization this practice is prohibited. Constants should be defined once and only once in the source code to be optimized. Forward reference or illegal argument for {pragma} Certain assembler directives, like REPEAT, IF, IFNOT, and EQU do not allow forward references (i.e., the label is defined in the source code AFTER its appearance in the pragma construct) as apart of their argument. Illegal address mode The addressing mode you have written for a given opcode is illegal or not supported by the 68HC05 instruction set. This commonly occurs with misplaced "#" symbols. A-2 Errors and Warnings Error Messages Illegal argument count You have specified too few or too many arguments for the given opcode or pragma. Check the construct syntax. Refer to Chapter 3 for the syntax of all HASM assembler directives. Illegal argument for {opcode/pragma} You have given an assembler directive or opcode an unexpected or unrecognized argument. Refer to Chapter 4 for the syntax of all HASM assembler directives. Illegal bit number: {number} The 68HC05 bit operations (BSET, BCLR, BRSET, BRCLR) all require that the bit number be specified as a part of the opcode. This bit number must be an integer between 0 and 7, inclusive. Numbers outside of this range will cause this error. Illegal index {value}, should be X You have specified the index to an indexed addressing instruction as something other than the X register. See Chapter 4 for details on indexed addressing. Illegal label name: {label} You have referenced a label that has not been defined. To define a label it must be apart of a SECTION directive or appear in the source in column one. See Chapters 2 and 4 for details. Illegal number of arguments for {opcode/pragma} You have specified too few or too many arguments for the given opcode or pragma. Check the construct syntax. Refer to Chapter 4 for the syntax of all HASM assembler directives. Illegal PRAGMA: {pragma} HASM could not identify the pragma listed in the error message. Check the spelling of the directive and verify that it is a valid HASM 3.0 pragma. A complete list of assembler directives in shown in Chapter 4. Illegal opcode/pragma: {opcode/pragma} HASM could not identify the opcode or pragma listed in the error message. Check the spelling of the instruction directive and verify that it is a valid HASM 3.0 pragma or 68HC05 mnemonic. A complete list of assembler directives in shown in Chapter 4. This error is also cause when label names are not placed in column one. Manual Title A-3 A Errors and Warnings Error Messages Illegal or out of range value You have specified a number as the argument of an opcode that is either too large for the given instruction or undefined. This commonly occurs when 16-bit numbers are given as arguments for 8-bit expressions, especially in immediate addressing instructions. Chapter 3 details all addressing modes and valid ranges associated with each mode. Illegal value {value} in statement {statement} You have constructed an assembler directive or 68HC05 assembly opcode incorrectly. Refer to Chapter 4 for the syntax of all HASM assembler directives. Missing argument for {opcode/pragma} The 68HC05 opcode or HASM assembler pragma specified in the error statement has not received all of the arguments (operands) required. Check your 68HC05 programming manual for details on the 68HC05 mnemonic assembly language. Chapter 4 details the usage of all HASM assembler pragmas. More than 20 nested #IF statements HASM allows a maximum of 20 IF and IFNOT statements to be nested within each other. Nested macro You have tried to call one macro within another macro. HASM 3.0 does not support the nesting or recursion of macros. Refer to Chapter 5 for more details. Range error in argument: {argument} You have specified a number as the argument of an opcode or pragma that is too large of small for the given instruction. This commonly occurs when 16-bit numbers are given as arguments for 8-bit expressions, especially in immediate addressing instructions. Chapter 3 details all addressing modes and valid ranges associated with each mode; refer to Chapter 4 for the syntax of all HASM assembler directives. Unmatched #ELSE (#ELSEIF) statement HASM has either detected an ELSE (or ELSEIF) statement outside of an IFENDIF construct or it has detected two consecutive #ELSE statements. There can be one and only one #ELSE statement in an IF-ENDIF construct. A-4 Errors and Warnings Warning Messages Unmatched #ENDIF statement HASM has detected an ENDIF statement without an IF conditional assembly construct. There must be exactly one ENDIF for each IF and IFNOT statement in the source file. Unmatched #ENDMACRO (#MACROEND) statement HASM has detected an ENDMACRO (or MACROEND) statement outside of a macro definition. See Chapter 5 for details on macro construction. Warning Messages HASM will also generate warning messages to inform the programmer that a something has happened during assembly that, while not prohibitive to assembly of the source file, still may be an undesired condition. Unlike errors, warning messages will not prevent the source file from being assembled. NOTE: Generation of warning messages can be turned off be using the /W command line switch. JMP location in close range You have used an extended JMP instruction in a location where it could be replaced with the relative addressing BRA opcode. This warning will not be issued when optimization is on since HASM will substitute the BRA opcode automatically. JSR location in close range You have used an extended JSR instruction in a location where it could be replaced with the relative addressing BSR opcode. This warning will not be issued when optimization is on since HASM will substitute the BSR opcode automatically. Macro label {label} is hidden by external label You have defined two labels with the same name, one inside a macro and one outside. While this is legal, any references to the identical label name, whether inside the macro or not, will reference the "global" (i.e. the label defined outside the macro) and not the "local" label. Refer to Chapter 5 for more details. Manual Title A-5 A Errors and Warnings Special Errors Redefinition of {variable} A variable definition has been redefined in the source code. This can cause unpredictable effects in the final assembly and should be avoided. Special Errors In addition to the error messages listed here, HASM also has a complete list of "program" errors that occur when HASM itself has problems assembling the source file. These errors usually concern allocation of memory and the "hash" look-up table generated during assembly. These errors occur quite infrequently and are almost never seen by the users of HASM. If one of these errors does occur, however, please note the cause of the error (i.e. computer setup, source file syntax, etc.) and notify us by phone at 1-800-4HARRIS or by e-mail at digiApps@harris.com. This will allow us to resolve these errors as quickly as possible. A-6 Errors and Warnings Special Errors Manual Title A-7 A A-8 Errors and Warnings Special Errors B HASM 3.0 Quick Reference B Appendix This chapter is included as a handy quick reference for the most commonly used HASM and 68HC05 commands. Command Line Switches Table 4. Valid HASM 3.0 Command Line Switches Switch Function Example E[=ext] Enable error file generation, set extension name /E /E=ERR H Suppress generation of hex file /H I=path Set standard search path for #include directive /i=c:\6805 L[=ext] Enable listing file generation, set extension name /L /L=LSS M Suppress macro expansion in listing file /M O Enable optimization /O S Enable generation of symbol file with .SYM extension /S W Suppress generation of warnings /W X=ext Set filename extension for hex file /X=s19 Manual Title B-1 B HASM 3.0 Quick Reference Arithmetic, Logic and Comparative Operators Arithmetic, Logic and Comparative Operators This page contains tables showing valid arithmetic, logical, and comparative operators and the valid forms of number representation in HASM 3.0 Table 5. Arithmetic, Logic and Comparative Operators Operator Example ( Left parenthesis 64*(label-4) ) Right parenthesis (value/5)-(6+value) + addition and unary plus 1+label - subtraction and unary minus value-$FF * multiplication address*$100 / division address/$100 ! exponentiation 2!bit_number & bitwise AND value&$FF | bitwise inclusive OR value|0x45 ^ bitwise exclusive OR label^$05 ~ bitwise invert ~(2!7) > greater than label>$100 < less than label<$100 = equal to label=$100 Table 6. Valid Numeric Forms in HASM B-2 Number (Decimal) Binary Hexadecimal Character 68 %1001000 $44 "D" 125 0B1111010 0x7D `z' 230 11100110B 0E6H HASM 3.0 Quick Reference Assembler Directives and Pragmas Assembler Directives and Pragmas Table 7. HASM 3.0 Assembler directives Directive Description Syntax .ascii Defines ASCII strings in memory .ascii "{string}" .ascii `{string}' boolean Reserves n bytes of memory boolean {n} byte Reserves n bytes of memory byte {n} .byte Defines one byte of memory .byte char Reserves n bytes of memory char db Defines one byte of memory db db db db ds Reserves n bytes of memory ds dw Defines one word of memory dw dw dw dw end End block of assembled code end equ Define a constant fcb Defines one byte of memory fcb {byte}, [{byte}, {byte}..] hex Defines one byte of memory hex {byte}, [{byte}, {byte} ..] integer Reserves n bytes of memory integer org Sets program location org rmb Reserves n bytes of memory rmb {n} rmw Reserves n words of memory rmw {n} section Sets and labels program location section {label}, {address} word Reserves n words of memory word .word Defines one word of memory fcb {byte}, [{byte}, {byte} ..] {n} {byte}, [{byte}, {byte}..] {byte} [{byte} {byte}..] "Text string" `Text String' {n} {word}, [{word}, {word}..] {word} [{word} {word}..] "Text string" `Text String' {label} equ {value} fdb Manual Title {n} {address} {n} {word}, [{word}, {word}..] B-3 B HASM 3.0 Quick Reference Assembler Directives and Pragmas Table 8. HASM 3.0 Assembler Pragmas Pragma Description Syntax ELSE Begin alternative assembly block to IF or IFNOT #else ELSEIF Begin alternative assembly block to IF or IFNOT #elseif ENDIF End conditional IF block assembly #endif ENDMACRO End macro definition #endmacro ENDREPEAT End block of repeated code #endrepeat ERROR Generate user defined error, stop assembly #error "{message}" IF Begin conditional assembled block of code #if {expression} IFNOT Begin conditional assembled block of code #ifnot {expression} INCLUDE Include additional source files for assembly. If enclosed in angle brackets, HASM uses standard search path defined by the /I=path command line switch. #include #include #include #include LIST Enable output to listing file #list MACRO Begin macro definition #macro {label} MACROEND End macro definition #macroend NOLIST Disable output to listing file #nolist NOOPT Disable optimization #noopt OPT Enable optimization #opt PAGE Insert form-feed into listing file #page REPEAT Begin block of repeated code #repeat {value} SET Define variable as TRUE #set {label} SETNOT Define variable as FALSE #setnot {label} {file} "{file}" `{file}' <{file}> NOTE: For all of the assembler pragmas listed above, the pragma delimiter "#" can be replaced with the "$" or "/" symbols interchangeably. B-4 HASM 3.0 Quick Reference Assembler Directives and Pragmas Manual Title B-5 B B-6 HASM 3.0 Quick Reference Assembler Directives and Pragmas Index Symbols dw 30 .ascii 27 .BYTE 28 .WORD 33 .word 33 E A addressing modes 21 direct 22 extended 22 immediate 22 indexed 23 indexed, 1 byte offset 23 indexed, 2 byte offset 24 indexed, no offset 23 inherent 21 allocation directives 27-33 table of B3 assembler directives 27-42 else 33 elseif 34 end 30 endif 34 endmacro 35 endrepeat 35 equ 31 error 35 error messages A1-A5 special A6 expressions arithmetic 20, B2 comparative 20, B2 logical 20, B2 F B fbd 31 fcb 31 batch files 8 boolean 28 byte 28 H hex 31 hex file 10 C char 28 command line running HASM from 5 switches 5 using batch files with 8 comments 17 customer support 3 D db 28 directives 27-42 data allocation 27-33 pragmas 33-42 tables of B3-B4 ds 29 I if 36 ifnot 37 include 38 installation 2 integer 31 L labels 17 licensing agreement 2 list 38 listing file 11 HASM 3.0 User's Guide M macro 39 macroend 39 macros comments in 46 defining in HASM 43 definiton of 2, 43 labels in 44 nesting 47 passing arguments to 46 pragma directives 43, B4 recursive 47 messages error A1-A5 special error A6 warning A5-A6 mnemonics 18 N nolist 39 noopt 40 numbering formats 19, B2 O opcodes supported by HASM 25 operators arithmetic 20, B2 comparative 20, B2 logical 20, B2 table of B2 opt 40 optimization 49-52 definition 49 enabling 49 extended jumps 51 extended subroutine calls 51 indexed addressing 50 org 31 output files 10 error file 13 hex file 10 listing file 11 7 Index symbol file 14 P page 40 pragmas 33-42 definiton of 2 table of B4 R repeat 40 rmb 32 rmw 32 S section 32 set 41 setnot 42 source file format of 17 switches, command line 5, B1 symbol file 14 Syntax 42 T terms, definition of assemble 2 machine code 2 macro 2 mnemonic 2 pragma 2 source code 2 W warning messages A5-A6 disabling A5 word 33 8 All Harris Semiconductor products are manufactured, assembled and tested under ISO9000 quality systems certification. Harris Semiconductor products are sold by description only. Harris Semiconductor reserves the right to make changes in circuit design and/or specifications at any time without notice. Accordingly, the reader is cautioned to verify that data sheets are current before placing orders. Information furnished by Harris is believed to be accurate and reliable. However, no responsibility is assumed by Harris or its subsidiaries for its use; nor for any infringements of patents or other rights of third parties which may result from its use. No license is granted by implication or otherwise under any patent or patent rights of Harris or its subsidiaries. Sales Office Headquarters For general information regarding Harris Semiconductor and its products, call 1-800-4-HARRIS NORTH AMERICA Harris Semiconductor P. O. Box 883, Mail Stop 53-210 Melbourne, FL 32902 TEL: 1-800-442-7747 (407) 729-4984 FAX: (407) 729-5321 EUROPE Harris Semiconductor Mercure Center 100, Rue de la Fusee 1130 Brussels, Belgium TEL: (32) 2.724.2111 FAX: (32) 2.724.22.05 S E M I C O N D U C T O R ASIA Harris Semiconductor PTE Ltd. No. 1 Tannery Road Cencon 1, #09-01 Singapore 1334 TEL: (65) 748-4200 FAX: (65) 748-0400