License

License Agreement
ASEM-51

Version 1.3
December 31, 2002

A fast, reliable, and handy macro assembler for the MCS-51 family of microcontrollers that is running on every PC with MS-DOS, Windows or Linux.

Copyright © 1994, 1996, 2002 by W.W. Heinz

All rights reserved.

Author: | W.W. Heinz
 | Preuschwitzer Str. 97a
 | D-95445 Bayreuth
 | Germany
 | phone | +49/921/4600987
 | mobile | +49/171/2691449
 | e-mail | w.w.heinz@web.de
 W.W. Heinz

Distribution Policy:

All the ASEM-51 programs, data, source and documentation files are copyright-reserved free software. You may use, copy and distribute it free of charge under the following conditions:

  1. Never change the copyright statement!
  2. The ASEM-51 package must be distributed in absolutely unmodified form, including all program, data, source and documentation files. If you distribute ASEM-51 to friends, associates, ftp or web sites, CD-ROM publishers, or to computer bulletin board systems (BBS), be sure to distribute it entirely and unchanged!
  3. ASEM-51 must not be sold for profit! No charge or payment may be levied or accepted for it. Of course this only applies to the ASEM-51 package itself, and not to the distribution media (i.e. BBS, disk, network, CD-ROM).
  4. ASEM-51 may be distributed with other free or commercial products (i.e. software, books, evaluation boards), if it is no functional part of these products, and without extra cost.
    Do not distribute ASEM-51 together with protected software!
  5. All source files provided with the ASEM-51 package may be modified for personal use, but not redistributed. Changes that may be of general interest should be sent to the author.
  6. Exceptions are only possible with a written permission of the author!

Implementation:

The ASEM-51 software package has been developed with:

Borland-Pascal mit Objekten 7.0 © Borland International 1992
Delphi 2.0 Client/Server Suite © Borland International 1996
FreePascal 1.0.6 © Florian Klämpfl 2002

ASEM-51 has not been produced according to ISO 9001 standards !!!
No formal process has been used during development, and there were no efforts in quality assurance or quality management!

Disclaimer:

This software is provided as it is, without warranty of any kind, expressed or implied, including but not limited to the implied warranties of merchantability and fitness for a particular purpose. The person using the software bears all risk as to the quality and performance of the software. The author will not be liable for any special, incidental, consequential, indirect or similar damages due to loss of data, time or profit or any other reason, even if the author or an agent of the author has been advised of the possibility of such damages.

ASEM-51 software, data and documentation are subject to change without notice!

ASEM-51 | is a trademark of | W.W. Heinz
MCS-51 | is a trademark of | Intel Corporation
Borland-Pascal | is a trademark of | Borland International, Inc.
Delphi | is a trademark of | Borland International, Inc.
MS-DOS | is a trademark of | Microsoft Corporation
Windows | is a trademark of | Microsoft Corporation
Linux | is a trademark of | Linus Torvalds
FreePascal | is a trademark of | Florian Klämpfl

Copyright © 1994, 1996, 2002 by W.W. Heinz

Last revised: December 31, 2002


ASEM-51 User's Manual

MCS-51 Microcontroller Family Macro Assembler

USER'S MANUAL

Version 1.3

December 31, 2002

TABLE OF CONTENTS

Foreword to Version 1.0
Foreword to Version 1.2
Foreword to Version 1.3
  1. Introduction
  2. Getting started
    1. DOS and Windows Implementation
      1. Files
      2. Installation under MS-DOS or Windows
      3. DOS Command Line Operation
      4. DOS Environment
      5. Running ASEM-51 in the Borland-IDE
      6. Running ASEM-51 from Windows 3.1x
      7. Running ASEM-51 from BRIEF
      8. The DOS Protected-Mode Assembler ASEMX
      9. The Win32 Console-Mode Assembler ASEMW
      10. The HEXBIN Utility
    2. Linux Implementation
      1. Files
      2. Installation under Linux
      3. Linux Command Line Operation
      4. Linux Environment
      5. The HEXBIN Utility
    3. The DEMO Program
  3. The ASEM-51 Assembly Language
    1. Statements
    2. Symbols
    3. Constants
    4. Expressions
    5. The 8051 Instruction Set
    6. Pseudo Instructions
    7. Segment Type
    8. Assembler Controls
      1. Primary Controls
      2. General Controls
    9. Predefined Symbols
    10. Conditional Assembly
      1. General IFxx Construction
      2. IFxx and ELSEIFxx Instructions
    11. Macro Processing
      1. Simple Callable Macros
      2. Macro Parameters
      3. Repeat Macros
      4. Local Symbols
      5. Macro Operators
      6. Premature End of a Macro Expansion
      7. Nested and Recursive Macro Calls
      8. Nested Macro Definitions
      9. Representation in the List File
  4. Compatibility with the Intel Assembler
    1. Restrictions
    2. Extensions
    3. Further Differences
  5. List File Format
  6. Support of 8051 Derivatives

APPENDIX

  1. ASEM-51 Error Messages
    1. Assembly Errors
    2. Runtime Errors
  2. HEXBIN Error Messages
    1. Conversion Errors
    2. Runtime Errors
  3. Predefined Symbols
  4. Reserved Keywords
  5. Specification of the Intel-HEX Format
  6. The ASCII Character Set
  7. Literature
  8. Trademarks
  9. 8051 Instructions in numerical Order
  10. 8051 Instructions in lexical Order

Copyright © 1994, 1996, 2002 by W.W. Heinz

Last revised: December 31, 2002


Foreword

Foreword to Version 1.0

Today microcontrollers are used in a wide range of applications from simple consumer electronic products to complex avionic components. Thus I was not very surprised to find an 80C31 on the videotext decoder board, I purchased some time ago. Since it had a poor user interface and many bugs, I thought I could do it better and so I began to look for an 8051 cross assembler.
But in contrast to the huge number of hardware components sold, the number of people developing microcontroller software seemed to be remarkable small, and so was the number of development tools on the market.
There was a very small number of good professional cross assemblers for $250 and up - too expensive for hobby purposes. Aside of useless demos, there were no restricted starter kits or school versions available.
I found also a few shareware and public domain assemblers. But either they were poor and not very reliable, or not very 8051-specific, or they used some kind of fantasy syntax that was 100 % compatible to itself, but far away from the Intel standard. I didn't like them all!
There seems to be a general lack of useful and affordable microcontroller development software. This is a pity, because their universality, simple architectures and low prices make microcontrollers so interesting especially for hobby and education.
So I decided to write a handy 8051 cross assembler for the PC.

And here it is:

ASEM-51 V1.0

I hope it will help to discover the wonderful world of microcontrollers.

Have fun!

Deisenhofen, July 19, 1994
W.W. Heinz

Foreword to Version 1.2

More than one year has passed, since I had released ASEM-51 V1.1 in October 1994. Although I didn't spend all the time on ASEM-51, V1.2 comes with several extensions, bug fixes, and numerous functional or internal improvements!
Highlights of the new version are a nearly perfectly featured list file with cross-reference and some new printing options, a bootstrap program for MCS-51 evaluation boards, and plenty of new *.MCU files. For detailed information see the ASEM-51 V1.2 Release Notes.

What I have learned through the last two years is that freeware is not free, neither for the author nor for the users.
ASEM-51 could not be made with nothing but numberless free hours, spent on pure software development. I also had to purchase a PASCAL development system, lots of microcontroller literature, and an 80C535 evaluation board.
The distribution of freeware seems to be a bigger problem than its development. First of all, one has to buy a modem. After that, it costs a lot of time, fees, trouble, and “interesting” discussions with the particular sysops, until the stuff is posted (or not) on several BBS and ftp sites.
To publish a program on shareware CD-ROMs, one has only to find out, which are the most suitable. For this, it is best to buy a dozen or two (and a CD-ROM drive), and to send the software to the publishers of those that seem to be the most popular.
The interested users finally have to purchase modems or CD-ROM drives, and pay the same fees, or buy the same CD-ROMs, to get the “freeware” again from these public sources.
After all, it may be cheaper, faster, and more convenient, to simply buy a professional software solution (if any) in the PC shop at the corner. But it's not half the fun!

ASEM-51 V1.1 had been distributed (and mirrored) to more than 60 ftp sites all over the world, uploaded to so many BBS, and published on at least two shareware CD-ROMs.
But I only received mails from 9 users, a local cockroach, and an international monster. The latter two asked me for permission, to sell ASEM-51 for (their) profit, and failed miserably.
Most of the user mails started with “I have copied your assembler from an ftp site, which I don't remember. It is looking fine on the first glance! By the way, have you got a data sheet of the 80Cxyz?”, or something like that.
During all the time, I have received one single error report only. Since it had been reported by phone, I couldn't reproduce it. Nevertheless two serious bugs have been fixed since version 1.1, but I have found them by myself in November 1995 both.
Sure ASEM-51 is no mainstream software, but to be honest, I am a little disappointed of the poor user feedback!

Finally, I should thank the persons, who helped me to release ASEM-51: Andreas Kies has tested all previous beta versions of the assembler. He has distributed the first releases, and maintained a free ASEM-51 support account right from the beginning.
Gabriele Novak has checked the orthography of all the documentation files. Werner Allinger has tested the latest beta version and the bootstrap program. Last but not least, I want to thank all interested users for their comments and suggestions.

Deisenhofen, January 22, 1996
W.W. Heinz

Foreword to Version 1.3

Six years have passed since I had released version 1.2.
I'm almost sure that most of my users thought that this was the last one!
It seems that I had always some spare time to support, maintain, change, extend, improve and port ASEM-51 over and over for many years, but never to publish an official new release.
But now, after six months of beta-testing, the time has come to unveil ASEM-51 Version 1.3 (Final Release). The most important new features are

  • new host platforms: Win32 and Linux (386)
  • macro processing
  • dramatically improved conditional assembly
  • output in absolute OMF-51 format (with debug information)
  • 37 new MCU files
  • documentation in both ASCII and HTML format

For detailed information on the numerous small extensions, improvements, and bug fixes, see the ASEM-51 V1.3 Release Notes.
Since fall 2001, ASEM-51 has an official home on the Internet, the ASEM-51 support website: http://plit.de/asem-51/

Credits:
Andreas Kies has tested all beta versions of the assembler. Without his Linux-knowhow, the Linux port would have been a very hard job.
Werner Allinger has tested the latest beta version, and has provided free webspace for the ASEM-51 website right from the beginning.
Axel Kielhorn has written the file DS5000.MCU.
Anders Sandström has sent me 87LPC762.MCU and 87LPC768.MCU.
Michael R. has contributed 80C32X2.MCU.
I also want to thank all the other users for their bug reports, contributions, comments and suggestions.

Bayreuth, December 31, 2002
W.W. Heinz


Getting started

II. Getting started

This chapter describes the ASEM-51 distributions, their installation on the supported host platforms, and how to use them in daily work.
  1. DOS and Windows Implementation
  2. Linux Implementation
  3. The DEMO Program


DOS and Windows Implementation

II.1 DOS and Windows Implementation

Until version 1.2, ASEM-51 was available in a real-mode implementation for plain MS-DOS only. Meanwhile a DOS protected-mode version and a Win32 console mode version have been added to the package.
In contrast to the new Linux implementation, all the DOS and Windows flavours are functionally identical and their basic operation can therefore be described together. Only a few minor differences and special features have to be discussed separately.
Since it should be possible to share program sources with the Linux version, all DOS and Windows executables are able to read ASCII files in both DOS and UNIX format, but write ASCII files in their native (DOS) format only.
  1. Files
  2. Installation under MS-DOS or Windows
  3. DOS Command Line Operation
  4. DOS Environment
  5. Running ASEM-51 in the Borland-IDE
  6. Running ASEM-51 from Windows 3.1x
  7. Running ASEM-51 from BRIEF
  8. The DOS Protected-Mode Assembler ASEMX
  9. The Win32 Console-Mode Assembler ASEMW
  10. The HEXBIN Utility


Files

II.1.1 Files

Your ASEM-51 distribution archive for DOS/Windows should contain the following groups of files:

1.) | ASEM_51.DOC | ASEM-51 User's Manual, ASCII format
 | DOCS.HTM | index file of the ASEM-51 documentation, HTML format
 | *.HTM | further pages of the HTML documentation
 | *.GIF | GIF images referenced by HTML pages
 | *.JPG | JPEG images referenced by HTML pages
 | ASEM.EXE | assembler (DOS real-mode)
 | ASEM.PIF | ASEM program information file for Windows 3.1x
 | ASEM.ICO | ASEM icon file for Windows 3.1x
 | ASEM2MSG.EXE | ASEM-51 message filter for Borland-IDE (DOS)
 | ASEM2MSG.PAS | Turbo-Pascal source of ASEM2MSG.EXE
 | ASEMX.EXE | assembler (DOS protected-mode)
 | ASEMX.PIF | ASEMX program information file for Windows 3.1x
 | ASEMX.ICO | ASEMX icon file for Windows 3.1x
 | DPMI16BI.OVL | Borland's 16-bit DPMI server (for ASEMX.EXE)
 | RTM.EXE | Borland's 16-bit DPMI runtime manager
 | ASEM32.BAT | runs ASEMX with Borland's 32-bit DPMI server
 | ASEMW.EXE | assembler (Win32 console-mode)
 | HEXBIN.EXE | hex-to-binary conversion utility (DOS)
 | HEXBINW.EXE | hex-to-binary conversion utility (Win32)
 | DEMO.A51 | a sample 8051 assembler program
 | *.MCU | processor definition files of 8051 derivatives (for a detailed list of MCU files see chapter “VI. Support of 8051 Derivatives”)

2.) | BOOT51.DOC | BOOT-51 User's Manual, ASCII format
 | BOOT51.HTM | index file of the BOOT-51 documentation, HTML format
 | BOOT51.A51 | BOOT-51 assembler source (requires ASEM-51 V1.3)
 | CUSTOMIZ.EXE | BOOT-51 customization utility
 | BOOT.BAT | batch file for application program upload
 | UPLOAD.BAT | called by BOOT.BAT only
 | COMPORT.EXE | setup utility for PC serial ports
 | RESET51.EXE | program to reset target system via PC ports
 | SLEEP.EXE | program to wait for the reset recovery time
 | BLINK.A51 | sample test program for BOOT-51

3.) | README.1ST | quick information, ASCII format
 | LICENSE.DOC | ASEM-51 License Agreement, ASCII format
 | RELEASE.130 | ASEM-51 Release Notes, ASCII format
 | SUPPORT.DOC | ASEM-51 Support Guide, ASCII format
 | INSTALL.BAT | creates a proper ASEM-51 installation under MS-DOS
 | KILLASEM.BAT | deletes all files of the ASEM-51 package (DOS)

The first group contains all files directly associated with the assembler. The second group contains all files directly associated with the bootstrap program. The third group contains general support and documentation files that apply to the whole package.


Installation under MS-DOS or Windows

II.1.2 Installation under MS-DOS or Windows

In principle ASEM-51 doesn't require a fuzzy software installation or configuration. In the simplest case you can copy all files of the package to your working directory, and enjoy the benefits of true plug-and-play compatibility!
On the other hand, an installation of ASEM-51 under MS-DOS is very simple:

  • Create a new, empty scratch directory on your harddisk.
  • Unpack your ASEM-51 distribution archive into this directory, or copy all files of the ASEM-51 package into it.
  • Make the scratch directory default, run the batch file INSTALL.BAT provided, and follow the instructions.

If you don't like anything that is running automatically, or things are not quite clear, ASEM-51 can also be installed manually as follows:

  • Create a new directory on your harddisk, e.g. C:\ASEM51.
  • Copy all files of the ASEM-51 package into this directory.
  • Append it to your PATH statement in file AUTOEXEC.BAT, e.g.

    PATH C:\DOS;C:\UTIL;C:\ASEM51
  • If this has not already been done while unpacking the distribution archive, create a subdirectory, e.g. C:\ASEM51\MCU, and move all the *.MCU files provided to this subdirectory, for better survey.
  • Create another subdirectory, e.g. C:\ASEM51\HTML, and move all the *.HTM, *.GIF and *.JPG files to this subdirectory, respectively. (To read that HTML manual, invoke your web browser and start with file C:\ASEM51\HTML\DOCS.HTM!)
  • Optionally define a DOS environment variable ASEM51INC in AUTOEXEC.BAT, to specify a search path for include files, e.g.

    SET ASEM51INC=C:\ASEM51\MCU;D:\MICROS\MCS51\INCL
  • For a proper operation of the Borland 16-bit DPMI server on computers with more than 16 MB RAM, be sure that EMM386.EXE (included in DOS 5.0 or later) is loaded, and define the environment variable DPMIMEM in AUTOEXEC.BAT as follows:

    SET DPMIMEM=MAXMEM 16383
  • Reboot your PC.

The installation batch file INSTALL.BAT should work properly on MS-DOS, Windows 3.1x, and Windows 9x systems. It has not yet been tested on other Windows versions. Especially for the NT-based Windows versions NT 4.0, 2000 and XP, a manual installation is recommended.


DOS Command Line Operation

II.1.3 DOS Command Line Operation

ASEM-51 provides full support of command line operation and batch capability as the best commercial development tools. (smile)
Nevertheless, it can be integrated into foreign development environments, if desired. The assembler is invoked by typing:

ASEM <source> [<object> [<listing>]] [<options>]

where <source> is the 8051 assembler source, <object> is the output file, and <listing> is the assembler list file. The parameters <object> and <listing> are optional. When omitted, the file names are derived from the <source> file name, but with extensions HEX (or OMF) and LST. All file names may be specified without extensions. In these cases, the assembler adds default extensions as shown below:

file | extension
<source> | .A51
<object> | .HEX (with /OMF-51 option: .OMF)
<listing> | .LST

If you want a file name to have no extension, terminate it with a '.'! Instead of file names you may also specify device names to redirect the output to character I/O ports. Device names may be terminated with a ':'! It is not checked, whether the device is existing or suitable for the task. Although it is possible to read the source file from a character device (e.g. CON:) instead of a file, this cannot be recommended: Since ASEM-51 is a two-pass assembler, it always reads the source file twice!

ASEM recognizes the following options:

 /INCLUDES:path1[;path2[; ... ;pathn]]
 /DEFINE:symbol[:value[:type]]
 /OMF-51
 /COLUMNS
 /QUIET

When the /INCLUDES option is used, the assembler searches the specified path for include files that cannot be found in the working directory. The path may be any number of directories separated by ';' characters. The directories will be searched from left to right. The path, specified with the /INCLUDES option, is searched before the path, defined with the (optional) DOS environment variable ASEM51INC!

The /DEFINE option is useful for selecting particular program variants from the command line that have been implemented with conditional assembly. It allows to define a symbol with a value and a segment type in the command line. Value and type are optional. The segment type of the symbol defaults to NUMBER, if omitted. The symbol value defaults to 0, if omitted. The symbol value may be any numerical constant. The symbol type must be one of the following characters:

    C   =   CODE
    D   =   DATA
    I   =   IDATA
    X   =   XDATA
    B   =   BIT
    N   =   NUMBER    (default)

By default, ASEM-51 generates an object file in Intel-HEX format. When the /OMF-51 option is specified, an absolute OMF-51 module is generated.

Options may be abbreviated as long as they remain unique!

Examples:

    0.)    ASEM
When invoked without parameters, the assembler displays a help screen:
           MCS-51 Family Macro Assembler ASEM-51 V1.3

           usage:   ASEM <source> [<object> [<listing>]] [options]

           options:      /INCLUDES:path1;path2;path3
                         /DEFINE:symbol[:value[:type]]
                         /OMF-51
                         /COLUMNS
                         /QUIET

    1.)    ASEM PROGRAM
will assemble the 8051 assembly language program PROGRAM.A51 and produce an Intel-HEX file PROGRAM.HEX and a listing PROGRAM.LST.
    2.)    ASEM TARZAN.ASM JANE JUNGLE.PRN
will assemble the 8051 assembly language program TARZAN.ASM and produce an Intel-HEX file JANE.HEX and a listing JUNGLE.PRN.
    3.)    ASEM PROJECT EPROM.
will assemble the 8051 assembly language program PROJECT.A51 and produce an Intel-HEX file EPROM and a listing PROJECT.LST.
    4.)    ASEM ROVER /OMF
will assemble the 8051 assembly language program ROVER.A51 and produce an absolute OMF-51 object module ROVER.OMF and a listing ROVER.LST.
    5.)    ASEM sample COM2: NUL
will assemble the 8051 assembly language program SAMPLE.A51, send the HEX file output to the serial interface COM2 and suppress the list file output by sending it to the NUL device.
    6.)    ASEM APPLICAT /INC:C:\ASEM51\MCU;D:\MICROS\8051\HEADERS
will assemble the program APPLICAT.A51, while all required include files will be searched first in the default directory, then in C:\ASEM51\MCU, and finally in D:\MICROS\8051\HEADERS.
    7.)    ASEM UNIVERSL /D:Eva_Board:8000H:C
will assemble the program UNIVERSL.A51, while the CODE symbol EVA_BOARD will be predefined with value 8000H during assembly.

When program errors are detected, they are flagged on the console. This may look as follows:

    MCS-51 Family Macro Assembler ASEM-51 V1.3

    APPLICAT.A51(14): must be known on first pass
    USERBITS.INC(6): attempt to divide by zero
    DEFINES.INC(37): symbol not defined
    APPLICAT.A51(20): symbol not defined
    APPLICAT.A51(27): no END statement found

         5 errors detected

Every error is flagged with the name of the source or include file, the local line number where it was found, and the error message itself. This output format makes it easy to integrate ASEM-51 into existing foreign development environments or workbenches.
A perfect fit for the Turbo C++ IDE (and perhaps others) can be reached with the /COLUMNS option. When specified, the column numbers of program errors are output additionally after the line numbers:

    MCS-51 Family Macro Assembler ASEM-51 V1.3

    APPLICAT.A51(14,12): must be known on first pass
    USERBITS.INC(6,27): attempt to divide by zero
    DEFINES.INC(37,18): symbol not defined
    APPLICAT.A51(20,18): symbol not defined
    APPLICAT.A51(27,1): no END statement found

         5 errors detected

If errors are detected in macro expansion lines, there is no corresponding location in the source file. Therefore, the error is flagged with the name of the source or include file, and the local line number from where the macro expansion has been invoked. (For callable macros this is the line with the macro call, and for repeat blocks this is the ENDM line.) To give the user a hint, the macro name and expansion line (and optionally column) number are inserted before the actual error message:

    MCS-51 Family Macro Assembler ASEM-51 V1.3

    UARTIO.A51(44,1): RECEIVE(3,22): segment type mismatch
    UARTIO.A51(87,1): REPT(4,19): symbol not defined
    UARTIO.A51(87,1): REPT(8,19): symbol not defined
    UARTIO.A51(87,1): REPT(12,19): symbol not defined

         4 errors detected

The expansion line number is the number of the expansion line within the corresponding macro expansion, starting with 1. If the error occurs during expansion of a repeat block, the keyword REPT replaces the macro name.

The /QUIET option suppresses all console output except error messages.

When terminating, ASEM-51 returns an exit code to the operating system:

situation | ERRORLEVEL
no errors | 0
program errors detected | 1
fatal runtime error | 2

Note: Warnings do not influence the exit code!


DOS Environment

II.1.4 DOS Environment

To specify a search path for include files, an optional environment variable ASEM51INC can be defined:

        SET ASEM51INC=<path>

<path> may be any number of directories separated by ';' characters. Be sure that the whole definition doesn't contain any blanks or tabs! If ASEM51INC is defined, the assembler searches the specified <path> for include files that can neither be found in the working directory, nor in the search path specified with the /INCLUDES option. The <path> directories will be searched from left to right.

Examples:

1.)    SET ASEM51INC=C:\ASEM51\MCU;D:\MICROS\MCS51\INCL
If include files can neither be found in the working directory, nor in the /INCLUDES path (if specified), the assembler searches next C:\ASEM51\MCU and finally D:\MICROS\MCS51\INCL.
2.)    SET ASEM51INC=C:\ASEM51\MCU;%PATH%
If ASEM51INC is defined as above in AUTOEXEC.BAT after the PATH statement, the assembler finally searches the directory C:\ASEM51\MCU and then all the directories, contained in the DOS program search path, from left to right!

The maximum length of <path> is limited to 255 characters. This cannot be exceeded with the SET command of the DOS command interpreter COMMAND.COM, but with third party command interpreters like 4DOS (max. 512 characters)!

Note that trailing blanks and tabs behind the names of environment variables seem to be considered significant under MS-DOS! If one subsequently defines

             SET ASEM51INC =C:\ASEM51\MCU
and          SET ASEM51INC=C:\8051\MCU
there will be two (!) entries concurrently in the DOS environment! However, the assembler will recognize the second one only. Since DOS doesn't truncate trailing blanks and tabs from variable names, the assembler can't do this either! That is why you should be sure, to always define the environment variable without blanks and tabs.


Running ASEM-51 in the Borland-IDE

II.1.5 Running ASEM-51 in the Borland-IDE

Turbo C++ (1.0 thru 3.0) users will appreciate the possibility to invoke ASEM-51 as a transfer program from the Borland IDE. (DOS versions only!)
For this, the filter program ASEM2MSG for the ASEM-51 error messages has been provided. To integrate ASEM-51 into the Borland IDE, perform the following steps:

  • Be sure that ASEM-51 has been installed properly as described before, or that ASEM.EXE and ASEM2MSG.EXE are somewhere in your PATH.
  • Start the Turbo C++ (or Borland C++) IDE for DOS.
  • For Turbo C++ 1.0, first click: Options | Full menus | ON
  • Click from the menu bar: Options | Transfer
  • When the “Transfer” dialog box is active, press the Edit button.
  • Now the “Modify/New Transfer Item” dialog box should be active.
    Fill in the following items:
    Program Title:   ASEM-~51
Program Path:    ASEM
Command Line:    $NOSWAP $SAVE CUR $CAP MSG(ASEM2MSG) $EDNAME /C
Translator:      [X]
Hot key:         Shift F8
    Then press the New button.
  • When returned to the “Transfer” dialog box, press the OK button.
  • Click from the menu bar: Options | Save | OK

Now it should be possible, to assemble the file in the active edit window with ASEM-51, when pressing Shift-F8. The error messages (if any) should appear in the “Message” window. You can browse through the errors, and jump into the source text by simply pressing Enter. This even works, if the error is not in the program itself, but in an include file!

Turbo-Pascal 7.0 users can also employ their Borland IDE for assembly. To integrate ASEM-51 into the Turbo-Pascal IDE, perform the following steps:

  • Be sure that ASEM-51 has been installed properly as described before, or that ASEM.EXE and ASEM2MSG.EXE are somewhere in your PATH.
  • Start the Turbo-Pascal 7.0 (or Borland-Pascal 7.0) IDE for DOS.
  • Click from the menu bar: Options | Tools
  • When the “Tools” dialog box is active, press the New button.
  • Now the “Modify/New Tool” dialog box should be active.
    Fill in the following items:
    Title:           ASEM-~5~1
Program path:    ASEM
Command line:    $NOSWAP $SAVE CUR $CAP MSG(ASEM2MSG) $EDNAME
Hot keys:        Shift+F8
    Then press the OK button.
  • When returned to the “Tools” dialog box, press the OK button.
  • Click from the menu bar: Options | Environment | Preferences
  • When the “Preferences” dialog box is active, disable the “Close on go to source” item in the “Options” checkbox. Then press the OK button.
  • Finally click from the menu bar: Options | Save

Now ASEM-51 can be invoked with Shift-F8, to assemble the program in the active edit window, while error messages (if any) appear in the “Messages” window.

Users of both Turbo C++ and Turbo-Pascal should prefer the Turbo C++ IDE. In the Turbo-Pascal 7.0 IDE, the /COLUMNS (or /C) option has no effect! Turbo-Pascal versions prior to 7.0 didn't implement the Tools menu.

Note that the transfer macro $SAVE CUR saves the contents of the active edit window (if modified), before ASEM.EXE is invoked! If your assembler program includes further source files (which may be currently loaded into other edit windows), better specify $SAVE ALL. This will save the contents of all (modified) edit windows to disk files, before invoking ASEM.EXE! If you are not sure, specify $SAVE PROMPT. This will prompt you for every (modified) edit window to save the contents before running ASEM.EXE. For further information on transfer macros, refer to the Borland online help!

Important: ASEM2MSG.EXE is not suitable for Win32 versions of the Borland IDE!


Running ASEM-51 from Windows 3.1x

II.1.6 Running ASEM-51 from Windows 3.1x

Of course ASEM and ASEMX are running fine in the Windows 3.1x DOS-Box! But for integration into the Windows 3.1x desktop, the files ASEM.PIF and ASEM.ICO have been provided. To insert ASEM-51 into a group of the Program Manager, perform the following steps:

  • Be sure that ASEM-51 has been installed properly for MS-DOS as described before.
  • Start Windows 3.1x and expand the Program Manager window to its full screen size representation, if necessary.
  • Focus the program group in which ASEM-51 is to be inserted, e.g. “Applications”.
  • Click from the Program Manager menu bar: File | New
  • When the “New Program Object” dialog box is active, choose the option “Program Item”, and click the OK button.
  • Now the “Program Item Properties” dialog box should be active.
    Fill in the following items:
    Description:          ASEM-51
Command Line:         ASEM.PIF
Working Directory:                  (whatever you want)
Shortcut Key:                       (whatever you want)
Run Minimized:        [ ]
    Then press the [Change Icon] button.
  • Now a message box appears with the error message “There are no icons available for the specified file”. Simply press the OK button.
  • The “Change Icon” dialog box should be displayed now. Fill in
    File Name:      ASEM.ICO
    and press the OK button. Now the ASEM-51 icon should be displayed in the icon field. Press the OK button again.
  • When returned to the “Program Item Properties” dialog box, press the OK button.

(In national Windows versions, things may look slightly different.)

Now ASEM.EXE can be invoked by simply double-clicking the ASEM-51 icon. After entering the program parameters in a corresponding dialog box, ASEM is running in a DOS window, which remains open after program termination, to let you have a look on the error messages.

In principle, the installation of the protected-mode assembler ASEMX.EXE can also be done as described above. However, the <Description> field should be filled with ”ASEM-51 XMS”, the <Command Line> should be ”ASEMX.PIF”, and the icon <File Name> should be ASEMX.ICO instead.


Running ASEM-51 from BRIEF

II.1.7 Running ASEM-51 from BRIEF

BRIEF 3.x users can integrate ASEM-51 into their editor by simply defining another DOS environment variable in their AUTOEXEC.BAT with

      SET BCA51=”ASEM %%s”
This specifies the command for compiling files with extension *.A51. After that, ASEM-51 can be invoked from BRIEF with Alt-F10.


The DOS Protected-Mode Assembler ASEMX

II.1.8 The DOS Protected-Mode Assembler ASEMX

In general, the proven real-mode assembler ASEM.EXE is sufficient also for very large programs. Nevertheless, it may be running out of memory, if a program contains a huge number of long user-defined symbols, or lots of large macro definitions.
To close the gap, the ASEM-51 package includes the new protected-mode assembler ASEMX.EXE. ASEMX is functionally identical to ASEM, but it can use extended memory, to meet extreme workspace requirements.
ASEMX is accompanied by Borland's 16-bit DPMI server DPMI16BI.OVL and runtime manager RTM.EXE. It requires a 286 CPU (or better), and at least 512 kB of free XMS memory (1 MB recommended)!
When ASEMX is invoked, DPMI16BI.OVL and RTM.EXE must be either
  • in your default directory,
  • where ASEMX.EXE is, or
  • somewhere in your PATH
During startup, the DPMI server tries to allocate all the remaining free XMS memory for use by ASEMX. If you don't want this, you can restrict the amount of allocated memory with the DOS environment variable DPMIMEM:
SET DPMIMEM=MAXMEM n
will restrict the XMS memory space, used for the DPMI interface, to n kB.
Never set n to a value greater than 16383!!!

In general, the Borland DPMI interface is very reliable and does normally not conflict with other memory managers. ASEMX will also run with other versions of DPMI16BI.OVL and RTM.EXE provided with various Borland software packages (except TC++ 3.0 and BC++ 3.1).

However, there is trouble ahead on systems with more than 16 MB RAM! Without specific installation, there is a fatal tendency to crash, hang, or even boot, whenever a DPMI program like ASEMX is invoked.
For proper operation of the DPMI interface, MS-DOS 5.0 (or later) is required, and EMM386.EXE must be loaded!
If EMM386.EXE has been loaded with parameters (e.g. NOEMS), the Borland 16-bit DPMI server cannot handle more than 16 MB! However, without parameters (i=nnnn, x=nnnn are o.k.) or with other DPMI servers there may be more. In these cases, ASEMX can use up to 64 MB of extended memory!

If ASEMX is running in a system environment with an own DPMI server, e.g. the Windows DOS-Box, RTM.EXE will detect this and use the active DPMI server instead of DPMI16BI.OVL. In this case, the environment variable DPMIMEM has no effect.
To restrict (or increase) the available XMS memory for the Windows 3.1x DOS prompt, change file DOSPRMPT.PIF in your WINDOWS directory with the Windows PIF file editor.
For further information on how to make more or less XMS memory available to application programs in other system environments, see the corresponding user manuals.

Another interesting alternative is the Borland 32-bit DPMI server with virtual memory management. It cannot be provided with the ASEM-51 package for license reasons, but is contained in Borland's Turbo-Assembler 4.0 and 5.0, Borland C++ 4.5x and 5.0x, and maybe others. It has originally been developed for the Borland command line tools, but it also works with ASEMX. It requires a 386 CPU (or better), and allows to extend the free physical memory with a swap file that can be created with the program MAKESWAP.EXE. Apart of that, the 32-bit DPMI server DPMI32VM.OVL and the runtime manager 32RTM.EXE are required.
The batch file ASEM32.BAT, provided with the ASEM-51 package, shows how to run ASEMX with 64 MB of virtual memory, using Borland's 32-bit DPMI server.


The Win32 Console-Mode Assembler ASEMW

II.1.9 The Win32 Console-Mode Assembler ASEMW

In principle, the DOS assemblers ASEM and ASEMX are also running in the Windows 9x/NT/2000/XP DOS-Box, but with some typical DOS-specific limitations: file names are restricted to the 8.3 format, path strings are limited to 64 characters, the real-mode assembler cannot access more than 640 kB RAM, and DOS support is getting worse and worse with every new Windows version.
To overcome these disadvantages, the ASEM-51 package comes with the new Win32 console-mode assembler ASEMW.EXE. ASEMW is functionally identical to ASEM, but it can handle long file names and benefits of the Win32 memory management, which allows to assemble astronomically large programs!

Hint: If you love file names with blanks in the middle, you have to enclose them in double quotes, e.g.
ASEMW “Test-Program for my 80C32 Evaluation-Board.a51”


The HEXBIN Utility (DOS)

II.1.10 The HEXBIN Utility

Most EPROM programmers are accepting the Intel-HEX object file format that is output by ASEM-51. However, for dumb EPROM burners and special purposes it might be useful to convert the HEX file to a pure binary image file. For this the conversion utility HEXBIN is provided. It is invoked as follows:

    HEXBIN <hex> [<bin>] [/OFFSET:o] [/LENGTH:l] [/FILL:f] [/QUIET]

where <hex> is the input file in Intel-HEX format, and <bin> is the binary output file. The parameter <bin> is optional. When omitted, the file name is derived from the <hex> file name, but with the extension BIN. All file names may be specified without extensions. In these cases, the program adds default extensions as shown below:

file | extension
<hex> | .HEX
<bin> | .BIN

If you want a file name to have no extension, terminate it with a '.'! Instead of file names you may also specify device names to redirect the output to character I/O ports. Device names may be terminated with a ':'! It is not checked, whether the device is existing or suitable for the task.

The binary file output can also be controlled with the options /OFFSET, /FILL and /LENGTH.

Normally the first byte in the binary file is the first byte of the HEX record with the lowest load address. If a number of dummy bytes is to be inserted on top of the file (e.g. for alignment in an EPROM image), this can be performed with the /OFFSET option:

/OFFSET:1000
would insert 4096 dummy bytes before the first byte of the first HEX record loaded. The offset must always be specified as a hex number. The default offset is 0.

Since there may be peepholes between the HEX records, a fill byte value can be defined with the /FILL option:

/FILL:0
would fill all peepholes between the HEX records with zero bytes as well as all the dummy bytes that might have been inserted with the /OFFSET or /LENGTH option. The fill byte value must always be specified as a hex number. The default fill byte is the EPROM-friendly FFH.

By default the last byte in the binary file is the last byte of the HEX record with the highest load address. If the binary file should have a well defined length, then a number of dummy bytes can be appended to the file (e.g. for exactly matching an EPROM length), this can be performed with the /LENGTH option:

/LENGTH:8000
would append as many dummy bytes behind the last byte of the file, that the total file length becomes exactly 32768 bytes. The file length must always be specified as a hex number.

When HEXBIN has been invoked with all the above options, it may display a file conversion report like this:

        Hex File Converter HEXBIN V2.3

                     offset:     1000H bytes
              first address:     9000H
               last address:     A255H
        fill peepholes with:       00H
        binary image length:     8000H bytes
The /QUIET option suppresses this console output, while error messages are displayed regardless.

Options may be abbreviated as long as they remain unique!

Examples:

0.)    HEXBIN
When invoked without parameters, HEXBIN displays a help screen:
       Hex File Converter HEXBIN V2.3

       usage:       HEXBIN <hexfile> [<binary>] [options]

       options:     /OFFSET:offset
                    /LENGTH:length
                    /FILL:fillbyte
                    /QUIET

1.)    HEXBIN PROGRAM
will convert the Intel-HEX file PROGRAM.HEX to a pure binary image file PROGRAM.BIN.
2.)    HEXBIN TARZAN.OBJ JUNGLE/FILL:E5
will convert the Intel-HEX file TARZAN.OBJ to a binary image file JUNGLE.BIN and fill all peepholes between the HEX file records with the binary value E5H.
3.)    HEXBIN PROJECT EPROM. /off:8000 /length:10000 /f:0
will convert the Intel-HEX file PROJECT.HEX to a binary image file EPROM, insert 32K dummy bytes on top of file, fill all peepholes and the dummy bytes with nulls, and extend the file to exactly 64K.

When terminating HEXBIN returns an exit code to the operating system:

situation | ERRORLEVEL
no errors | 0
conversion errors detected | 1
fatal runtime error | 2

There is also a Win32 console-mode version of HEXBIN: HEXBINW.EXE!
HEXBINW is functionally identical to HEXBIN, but can handle long file names.


Linux Implementation

II.2 Linux Implementation

Until version 1.2, ASEM-51 was available for MS-DOS only.
To get rid of the original DOS “look and feel”, many interfaces to the operating system had to be modified or rewritten, e.g. command line processing, console I/O, file handling, UNIX environment, and memory management. Furthermore, the general behaviour of the programs had to be adapted to UNIX conventions. A certain rest of DOS flavour may still be remaining though.
On the other hand, the Linux binaries are able to read ASCII files in both DOS and UNIX format. However, ASCII files are always written in UNIX format.
All these differences make it necessary to describe the Linux implementation in a separate section!

  1. Files
  2. Installation under Linux
  3. Linux Command Line Operation
  4. Linux Environment
  5. The HEXBIN Utility


Files

II.2.1 Files

Your ASEM-51 distribution archive for Linux should contain the following groups of files:

1.) | asem_51.doc | ASEM-51 User's Manual, ASCII format
 | docs.htm | index file of the ASEM-51 documentation, HTML format
 | *.htm | further pages of the HTML documentation
 | *.gif | GIF images referenced by HTML pages
 | *.jpg | JPEG images referenced by HTML pages
 | asem | assembler (Linux 386)
 | asem.1 | man-page for asem
 | hexbin | hex-to-binary conversion utility (Linux 386)
 | hexbin.1 | man-page for hexbin
 | demo.a51 | a sample 8051 assembler program
 | *.mcu | processor definition files of 8051 derivatives (for a detailed list of MCU files see chapter “VI. Support of 8051 Derivatives”)

2.) | boot51.doc | BOOT-51 User's Manual, ASCII format
 | boot51.htm | index file of the BOOT-51 documentation, HTML format
 | boot51.a51 | BOOT-51 assembler source (for ASEM-51 V1.3 and up)
 | customiz | BOOT-51 customization utility (Linux 386)
 | customiz.1 | man-page for customiz
 | boot | shell script for application program upload
 | boot.1 | man-page for boot
 | upload | called by boot only (generic version)
 | upload.new | ”new” upload (optimized for stty 2.0 or later)
 | reset51 | program to reset target system via PC ports
 | reset51.1 | man-page for reset51
 | blink.a51 | sample test program for BOOT-51

3.) | README.1ST | quick information, ASCII format
 | license.doc | ASEM-51 License Agreement, ASCII format
 | release.130 | ASEM-51 Release Notes, ASCII format
 | support.doc | ASEM-51 Support Guide, ASCII format
 | install.sh | creates a proper ASEM-51 installation under Linux
 | uninst51.sh | deletes all files of the ASEM-51 package (Linux)

The first group contains all files directly associated with the assembler. The second group contains all files directly associated with the bootstrap program. The third group contains general support and documentation files that apply to the whole package.


Installation under Linux

II.2.2 Installation under Linux

ASEM-51 for Linux is available as a tar archive and an rpm package.
If you have got the rpm package, login as root and simply type

rpm -i asem51-1.3-1.i386.rpm

The rpm package has been tested on S.u.S.E.-Linux only, but should also work on other Linux distributions that meet the FHS directory standard.
If you have got the tar archive, perform the following steps:

gzip -d asem51-1.3-ELF.tar.gz
tar xvf asem51-1.3-ELF.tar
cd asem51
sh install.sh

If you are installing ASEM-51 as root (preferred), the installation script install.sh will install the whole package in /usr/local/share/asem-51/1.3, and establish some symbolic links in /usr/local/bin and /usr/local/man/man1.

If you are installing ASEM-51 under another user-id, install.sh tries to install the software in your home directory under ~/asem-51/1.3, and establish some symbolic links in ~/bin and ~/man/man1.

For details see the messages, install.sh is displaying on the console, and do some fine-tuning accordingly:

If you haven't installed ASEM-51 as root, it may be necessary to add ~/bin to your PATH, and ~/man to your MANPATH.

To specify a search path for the include files *.mcu provided, you can define an optional environment variable ASEM51INC. For this, bash, ksh, and sh users should insert the following lines into their .profile file:

ASEM51INC=/usr/local/share/asem-51/1.3/mcu
export ASEM51INC

csh, tcsh, and zsh users should insert the following line into their .login file respectively:

setenv ASEM51INC /usr/local/share/asem-51/1.3/mcu

If you have installed ASEM-51 in your home directory, ASEM51INC should point to ~/asem-51/1.3/mcu of course.

To read the HTML manuals, invoke your web browser and bookmark the index page

/usr/local/share/asem-51/1.3/html/docs.htm | (installation as root)
~/asem-51/1.3/html/docs.htm | (local installation)

Note that you cannot reset your 8051 target system with a PC printer port, if you haven't installed ASEM-51 as root! (For details see the BOOT-51 documentation provided.)

If you have installed ASEM-51, but you don't like it, you can easily uninstall it. If you have installed the rpm package, simply type

rpm -e asem51

If you have installed the generic tar archive, be sure to uninstall ASEM-51 under the same user-id you previously used for installation! Run

uninst51.sh

and that's it.


Linux Command Line Operation

II.2.3 Linux Command Line Operation

Under Linux, the assembler is invoked by typing:

asem [<options>] <source> [<object> [<listing>]]
where <source> is the 8051 assembler source, <object> is the output file, and <listing> is the assembler list file.
All file names that are specified explicitly, are left unchanged.
The parameters <object> and <listing> are optional. When omitted, the <object> file name is derived from the <source> file name, but with extension “.hex” (or “.omf”). When the <listing> file name is omitted, it is derived from the <object> file name, but with extension “.lst”:

file | extension
<object> | .hex (with -o option: .omf)
<listing> | .lst

Instead of file names you may also specify device names to redirect the output to I/O devices. Device names are assumed to start with “/dev/”. Of course no extensions will be added to device names!
It is not checked, whether the device is existing or suitable for the task. Although it is possible to read the source file from a character device instead of a file, this cannot be recommended: Since ASEM-51 is a two-pass assembler, it always reads the source file twice!
The maximum length of a file parameter is limited to 255 characters!

asem recognizes the following options:

short options | long options
-i path1:path2:path3 | --includes=path1:path2:path3
-d symbol[:value[:type]] | --define=symbol[:value[:type]]
-o | --omf-51
-c | --columns
-v | --verbose

The short and long options in the same row are equivalent.
Long options may be abbreviated as long as they remain unique.
All option names are case-sensitive!

When the --includes option is used, the assembler searches the specified path for include files that cannot be found in the working directory. The path may be any number of directories separated by ':' characters. The directories will be searched from left to right.
The path, specified with the --includes option, is searched before the path, defined with the (optional) environment variable ASEM51INC!
The maximum path length is limited to 255 characters.

The --define option is useful for selecting particular program variants from the command line that have been implemented with conditional assembly. It allows to define a symbol with a value and a segment type in the command line. Value and type are optional. The segment type of the symbol defaults to NUMBER, if omitted. The symbol value defaults to 0, if omitted. The symbol value may be any numerical constant. The symbol type must be one of the following characters:

    C   =   CODE
    D   =   DATA
    I   =   IDATA
    X   =   XDATA
    B   =   BIT
    N   =   NUMBER    (default)

By default, ASEM-51 generates an object file in Intel-HEX format. When the --omf-51 option is specified, an absolute OMF-51 module is generated.

Examples:

0.)    asem
When invoked without parameters, the assembler displays a help screen:
           MCS-51 Family Macro Assembler ASEM-51 V1.3

           usage:     asem [options] <source> [<object> [<listing>]]

           options:   -i   --includes=path1:path2:path3
                      -d   --define=symbol[:value[:type]]
                      -o   --omf-51
                      -c   --columns
                      -v   --verbose

1.)    asem program.a51
will assemble the 8051 assembly language program program.a51 and produce an Intel-HEX file program.hex and a listing program.lst.
2.)    asem tarzan.asm jane jungle.prn
will assemble the 8051 assembly language program tarzan.asm and produce an Intel-HEX file jane and a listing jungle.prn.
3.)    asem project eprom
will assemble the 8051 assembly language program project and produce an Intel-HEX file eprom and a listing eprom.lst.
4.)    asem -o rover.a51
will assemble the 8051 assembly language program rover.a51 and produce an absolute OMF-51 object module rover.omf and a listing rover.lst.
5.)    asem sample.a51 /dev/ttyS0 /dev/null
will assemble the 8051 assembly language program sample.a51, send the HEX file output to the serial interface /dev/ttyS0 and suppress the list file output by sending it to the /dev/null device.
6.)    asem -i /usr/local/include/asem-51:~/8051/inc app.a51
will assemble the program app.a51, while all required include files will be searched first in the default directory, then in /usr/local/include/asem-51, and finally in ~/8051/inc.
7.)    asem --define=Eva_Board:8000H:C universal.a51
will assemble the program universal.a51, while the CODE symbol EVA_BOARD will be predefined with value 8000H during assembly.

When program errors are detected, corresponding error messages are output to standard error. This may look as follows:

    applicat.a51(14): must be known on first pass
    userbits.inc(6): attempt to divide by zero
    defines.inc(37): symbol not defined
    applicat.a51(20): symbol not defined
    applicat.a51(27): no END statement found

Every error is flagged with the name of the source or include file, the local line number where it was found, and the error message itself. This output format provides a hook to run ASEM-51 from third-party IDEs. A perfect fit may be reached with the --columns option. When specified, the column numbers of program errors are output additionally after the line numbers:

    applicat.a51(14,12): must be known on first pass
    userbits.inc(6,27): attempt to divide by zero
    defines.inc(37,18): symbol not defined
    applicat.a51(20,18): symbol not defined
    applicat.a51(27,1): no END statement found

If errors are detected in macro expansion lines, there is no corresponding location in the source file. Therefore, the error is flagged with the name of the source or include file, and the local line number from where the macro expansion has been invoked. (For callable macros this is the line with the macro call, and for repeat blocks this is the ENDM line.) To give the user a hint, the macro name and expansion line (and optionally column) number are inserted before the actual error message:

    uartio.a51(44,1): RECEIVE(3,22): segment type mismatch
    uartio.a51(87,1): REPT(4,19): symbol not defined
    uartio.a51(87,1): REPT(8,19): symbol not defined
    uartio.a51(87,1): REPT(12,19): symbol not defined

The expansion line number is the number of the expansion line within the corresponding macro expansion, starting with 1. If the error occurs during expansion of a repeat block, the keyword REPT replaces the macro name.

By default, ASEM-51 is totally “quiet”, if no errors are detected. If the --verbose option is specified, additional product, version, and error summary information is written to standard output:

    MCS-51 Family Macro Assembler ASEM-51 V1.3

    uartio.a51(44,1): RECEIVE(3,22): segment type mismatch
    uartio.a51(87,1): REPT(4,19): symbol not defined
    uartio.a51(87,1): REPT(8,19): symbol not defined
    uartio.a51(87,1): REPT(12,19): symbol not defined

         4 errors detected

When terminating, ASEM-51 returns an exit code to the calling process:

situation | exit code
no errors | 0
program errors detected | 1
fatal runtime error | 2

Note: Warnings are also output on standard error, but do not influence the exit code!


Linux Environment

II.2.4 Linux Environment

To specify a search path for include files, an optional environment variable ASEM51INC can be defined:

1.) For bash, ksh, and sh:

    ASEM51INC=<path>
    export ASEM51INC

2.) For csh, tcsh, and zsh:

    setenv ASEM51INC <path>

<path> may be any number of directories separated by ':' characters. Be sure that the whole definition doesn't contain any blanks or tabs!
If ASEM51INC is defined, the assembler searches the specified <path> for include files that can neither be found in the working directory, nor in the search path specified with the --includes option.
The <path> directories will be searched from left to right.

Examples:

1.) bash:
      ASEM51INC=/usr/local/include/asem-51:~/micros/mcs51/inc
      export ASEM51INC
If include files can neither be found in the working directory, nor in the --includes path (if specified), the assembler searches next /usr/local/include/asem-51 and finally ~/micros/mcs51/inc.
2.) csh:
      setenv ASEM51INC /usr/local/include/asem-51
If ASEM51INC is defined as above in .login, the assembler finally searches the directory /usr/local/include/asem-51 for include files.

The maximum length of <path> is limited to 255 characters.


The HEXBIN Utility (Linux)

II.2.5 The HEXBIN Utility

Most EPROM programmers are accepting the Intel-HEX object file format that is output by ASEM-51. However, for dumb EPROM burners and special purposes it might be useful to convert the HEX file to a pure binary image file. For this the conversion utility hexbin is provided. It is invoked as follows:

    hexbin [<options>] <hexfile> [<binary>]

where <hexfile> is the input file in Intel-HEX format, and <binary> is the binary output file. All file names that are specified explicitly, are left unchanged. The parameter <binary> is optional. When omitted, the file name is derived from the <hexfile>, but with the extension “.bin”.
The maximum length of a file parameter is limited to 255 characters!

Instead of file names you may also specify device names to redirect the input or output to I/O devices. Device names are assumed to start with “/dev/”. Of course no extensions will be added to device names!
It is not checked, whether the device is existing or suitable for the task.

hexbin recognizes the following options:

short options | long options
-o <offset> | --offset=<offset>
-l <length> | --length=<length>
-f <fillbyte> | --fill=<fillbyte>
-v | --verbose

The short and long options in the same row are equivalent.
Long options may be abbreviated as long as they remain unique.
All option names are case-sensitive!

The binary file output can be controlled with the options --offset, --fill and --length.

Normally the first byte in the binary file is the first byte of the HEX record with the lowest load address. If a number of dummy bytes is to be inserted on top of the file (e.g. for alignment in an EPROM image), this can be performed with the --offset option:

--offset=1000
would insert 4096 dummy bytes before the first byte of the first HEX record loaded. The offset must always be specified as a hex number. The default offset is 0.

Since there may be peepholes between the HEX records, a fill byte value can be defined with the --fill option:

--fill=0
would fill all peepholes between the HEX records with zero bytes as well as all the dummy bytes that might have been inserted with the --offset or --length option. The fill byte value must always be specified as a hex number. The default fill byte is the EPROM-friendly FFH.

By default the last byte in the binary file is the last byte of the HEX record with the highest load address. If the binary file should have a well defined length, then a number of dummy bytes can be appended to the file (e.g. for exactly matching an EPROM length), this can be performed with the --length option:

--length=8000
would append as many dummy bytes behind the last byte of the file, that the total file length becomes exactly 32768 bytes. The file length must always be specified as a hex number.

By default, hexbin is totally “quiet”, if no errors are detected. If the --verbose option is specified, additional product and version information, and a file conversion report is written to standard output:

        Hex File Converter HEXBIN V2.3

                     offset:      FF0H bytes
              first address:     7FF0H
               last address:     8255H
        fill peepholes with:       A5H
        binary image length:     2000H bytes

Examples:

0.)    hexbin
When invoked without parameters, hexbin displays a help screen:
       Hex File Converter HEXBIN V2.3

       usage:      hexbin [options] <hexfile> [<binary>]

       options:   -o   --offset=<offset>
                  -l   --length=<length>
                  -f   --fill=<fillbyte>
                  -v   --verbose

1.)    hexbin program.hex
will convert the Intel-HEX file program.hex to a pure binary image file program.bin.
2.)    hexbin -f E5 tarzan.obj jungle.bin
will convert the Intel-HEX file tarzan.obj to a binary image file jungle.bin and fill all peepholes between the HEX file records with the binary value E5H.
3.)    hexbin --off=8000 -l10000 --fill=0 project.hex eprom
will convert the Intel-HEX file project.hex to a binary image file eprom, insert 32K dummy bytes on top of file, fill all peepholes and the dummy bytes with nulls, and extend the file to exactly 64K.

When terminating hexbin returns an exit code to the calling process:

situation | exit code
no errors | 0
conversion errors detected | 1
fatal runtime error | 2


The DEMO Program

II.3 The DEMO Program

For getting started with a new assembler, it is always helpful to have a program that can be assembled with it. For this purpose, the 8051 assembler program DEMO.A51 is provided, which can be used for a first test of the ASEM-51 installation. For this, you should either have installed ASEM-51 as described above, or keep all files of the ASEM-51 package directly in your working directory!

Under MS-DOS or in a Windows DOS-Box simply type

ASEM DEMO
HEXBIN DEMO
at the DOS prompt. ASEM and HEXBIN should finish without errors and you should have the following new files on your disk:
DEMO.HEX          Intel-HEX file
DEMO.LST          assembler list file of DEMO.A51
DEMO.BIN          binary image file of DEMO.HEX

Under Linux type

asem demo.a51
hexbin demo.hex
Again asem and hexbin should finish without errors and you should have the following new files on your disk:
demo.hex          Intel-HEX file
demo.lst          assembler list file of demo.a51
demo.bin          binary image file of demo.hex

If something goes wrong, either ASEM-51 is not properly installed, there may be files missing in your distribution, or the assembler simply cannot find the include file 8052.mcu!
demo.a51 may also serve as a sample assembler program that includes examples for (nearly) all machine instructions, pseudo instructions, assembler controls, and meta instructions that have been implemented in ASEM-51. Whenever in doubt how to use a particular command, demo.a51 may be a valuable help.
Unlike other assemblers, the ASEM-51 list file is no alibi feature! It is really instructive to compare the original source to the generated code in the listing.


The ASEM-51 Assembly Language

III. The ASEM-51 Assembly Language

The user should be familiar with 8051 microcontrollers and assembly language programming. This manual will not explain the architecture of the MCS-51 microcontroller family nor will it discuss the basic concepts of assembly language programming. It only describes the general syntax of assembler statements and the assembler instructions that have been implemented in ASEM-51.
  1. Statements
  2. Symbols
  3. Constants
  4. Expressions
  5. The 8051 Instruction Set
  6. Pseudo Instructions
  7. Segment Type
  8. Assembler Controls
  9. Predefined Symbols
  10. Conditional Assembly
  11. Macro Processing


Statements

III.1 Statements

Source files consist of a sequence of statements of one of the forms:

[symbol:]  [instruction [arguments]]     [;comment]

 symbol     instruction  argument        [;comment]

$control   [(argument)]                  [;comment]

Everything that is written in brackets is optional.
The maximum length of source code lines is 255 characters.
Everything from the ';' character to the end of line is assumed to be commentary. Blank lines are considered to be commentary, too.
The lexical elements of a statement may be separated by blanks and tabs.
Aside of character string constants, upper and lower case letters are equivalent.

Examples:

HERE:	MOV	A,#0FFH		;define label HERE and load A with FFH
YEAR	EQU	2002		;define symbol for current year

$INCLUDE (80C517.MCU)		;include SAB80C517 register definitions


Symbols

III.2 Symbols

Symbols are user-defined names for addresses, numbers or macros.
Their maximum significant length is 31 characters. They can be even longer, but everything behind the first 31 characters is ignored. Symbols may consist of letters, digits, '_' and '?' characters. A symbol name must not start with a digit! Upper and lower case letters are considered to be equivalent.
Note: Assembly language keywords must not be redefined as user symbols!

Example:

Is_this_really_a_SYMBOL_?       ;is a legal symbol name!


Constants

III.3 Constants

Numeric constants consist of a sequence of digits, followed by a radix specifier. The first character must always be a decimal digit. The legal digits and radix specifiers are:

constant | digits | radix
binary | 0 ... 1 | B
octal | 0 ... 7 | Q or O
decimal | 0 ... 9 | D or none
hex | 0 ... F | H

Thus, for example, the following constants are equivalent:

1111111B      binary
    177Q      octal
    177o      octal
     127      decimal
    127d      decimal
    07FH      hex

Character constants may be used wherever a numeric value is allowed. A character constant consists of one or two printing characters enclosed in single or double quotes. The quote character itself can be represented by two subsequent quotes. For example:

 'X'       8 bit constant:       58H
”a@”      16 bit constant:     6140H
''''       8 bit constant:       27H

In DB statements, character constants may have any length. In this case, we call it a character string. For example:

'This is only text!'


Expressions

III.4 Expressions

Arithmetic expressions are composed of operands, operators and parentheses. Operands may be user-defined symbols, constants or special assembler symbols. All operands are treated as unsigned 16-bit numbers. Special assembler symbols, that can be used as operands are:

AR0, ... , AR7 | direct addresses of registers R0 thru R7
$ | the location counter of the currently active segment (start address of the current assembler statement)

The following operators are implemented:

Unary Operators
Operator | Operation | Definition
+ | identity | +x = x
- | two's complement | -x = 0-x
NOT | one's complement | NOT x = FFFFH-x
HIGH | high order byte |
LOW | low order byte |

Binary Operators
Operator | Operation | Result
+ | unsigned addition |
- | unsigned subtraction
* | unsigned multiplication
/ | unsigned division
MOD | unsigned remainder
SHL | logical shift left
SHR | logical shift right
AND | logical and
OR | logical or
XOR | exclusive or
. | bit operator used for bit-adressable locations
EQ or = | equal to | 0 if FALSE, FFFFH if TRUE
NE or <> | not equal to
LT or < | less than
LE or <= | less or equal than
GT or > | greater than
GE or >= | greater or equal than

Operators that are no special characters but keywords as SHR or AND must be separated from their operands by at least one blank or tab. In general expressions are evaluated from left to right according to operator precedence, which may be overridden by parentheses. Parentheses may be nested to any level.
Expressions always evaluate to unsigned 16-bit numbers, while overflows are ignored. When an expression result is to be assigned to an 8-bit quantity, the high byte must be either 00 or FF.

Operator Precedence
Operator(s) | Type | Precedence
( ) |  | highest
+ - NOT HIGH LOW | unary |
. |
* / MOD
SHL SHR
+ - | binary
EQ = NE <> LT < LE <= GT > GE >= |
AND
OR XOR |  | lowest

Example:

The expression
        P1.((87+3)/10 AND -1 SHR 0DH)
will evaluate to 91H.


The 8051 Instruction Set

III.5 The 8051 Instruction Set

ASEM-51 implements all 8051 machine instructions including generic jumps and calls. The assembler implements two instructions

    JMP	<address>
    CALL	<address>

that do not represent a specific opcode: generic jump and call. These instructions will always evaluate to a jump or call, not necessarily the shortest, that will reach the specified address.
JMP may assemble to SJMP, AJMP or LJMP, while CALL can only evaluate to ACALL or LCALL. Note that the assembler decision may not be optimal. For code addresses that are forward references, the assembler always generates LJMP or LCALL respectively. However, for backward references this is a powerful tool to reduce code size without extra trouble.

With the $PHILIPS control, ASEM-51 can be switched to the reduced instruction set of the Philips 83C75x family of microcontrollers. This disables the LJMP, LCALL, and MOVX instructions as well as the XDATA and XSEG pseudo instructions, and generic jumps and calls will always assemble to absolute addressing.

The rest of the 8051 instruction mnemonics is listed in Appendix D. Appendices I and J are containing tables of all 8051 instructions with their opcodes, mnemonics, arguments, lengths, affected flags and durations. The comprehensive example program DEMO.A51 provided shows all the 8051 instructions in a syntactical context.

For detailed information on the Intel MCS-51 architecture and instruction set refer to the MCS® 51 Microcontroller Family User's Manual. (Requires full Internet access!)

All MCS-51 instruction mnemonics are copyright © by Intel Corporation!


Pseudo Instructions

III.6 Pseudo Instructions

In the subsequent paragraphs, all ASEM-51 pseudo instructions are described. Lexical symbols are written in lower case letters, while assembler keywords are written in upper case.
Instruction arguments are represented by <arg>, <arg1> or something like that. Numeric expressions are represented by <expr>, <expr1> and so on. Syntax elements enclosed in brackets are optional.
The ellipsis “...” means always “a list with any number of elements”.

DB <arg1> [,<arg2> [,<arg3> ... ]] define bytes

The DB instruction reserves and initializes a number of bytes with the values defined by the arguments. The arguments may either be expressions (which must evaluate to 8-bit values) or character strings of any length. DB is only allowed in the CODE segment!

Example: DB 19,'January',98,(3*7+12)/11

DW <expr1> [,<expr2> [,<expr3> ... ]] define words

The DW instruction reserves and initializes a number of words with the values defined by the arguments. Every argument may be an arbitrary expression and requires two bytes of space. DW is only allowed in the CODE segment!

Example: DW 0,0C800H,1999,4711

DS <expr> define space

Reserves a number of uninitialized bytes in the current segment. The value of <expr> must be known on pass 1! DS is allowed in every segment, except in the BIT segment!

Example: DS 200H

DBIT <expr> define bits

Reserves a number of uninitialized bits. The value of <expr> must be known on pass 1! DBIT is only allowed in the BIT segment!

Example: DBIT 16

NAME <symbol> define module name

Defines a module name for the OMF-51 object file. If no module name is defined, the module name is derived from the source file name. When generating Intel-HEX file output, the NAME instruction has no effect. The module name must be a legal assembler symbol. Only one NAME instruction is allowed within the program. The symbol however, may be redefined in the subsequent program.

Example: NAME My_1st_Program

ORG <expr> origin of segment location

Sets the location counter of the current segment to the value <expr>. The value of <expr> must be known on pass 1! It must be greater or equal to the segment base address. The default value of all location counters at program start is 0.

Example: ORG 08000H

USING <expr> using register bank

Sets the register bank used to <expr>, which must be in the range of 0...3. The USING instruction only affects the values of the special assembler symbols AR0, ... , AR7 representing the direct addresses of registers R0, ... , R7 in the current register bank. The value of <expr> must be known on pass 1! The default value for the register bank is 0.

Example: USING 1

END end of program

This must be the last statement in the source file. After the END statement only commentary and blank lines are allowed!

Example: END       ;end of program

<symbol> EQU <expr> | define numeric constant
<symbol> EQU <reg> | define invariant register
<symbol> SET <expr> | define numeric variable
<symbol> SET <reg> | define variable register

The EQU instruction defines a symbol for a numeric constant or a register. If a numeric expression <expr> is assigned to the symbol, it will be of the type NUMBER. If a register <reg> is assigned to the symbol, it will be of the type REGISTER. <reg> may be one of the special assembler symbols A, R0, R1, R2, R3, R3, R4, R5, R6, or R7.
A symbol once defined with EQU can never be changed!
The SET instruction is working quite similar to EQU. However, symbols defined with SET can be redefined with subsequent SET instructions! The values of <expr> and <reg> must be known on pass 1!
A symbol that has been SET, cannot be redefined with EQU!
A symbol that has been EQU'd cannot be reSET!
On pass 2, forward references to a SET symbol always evaluate to the last value, the symbol has been SET to on pass 1.
Register symbols can be used as instruction operands within the whole program instead of the corresponding registers.
Forward references to register symbols are not allowed!

Examples:
           MAXMONTH  EQU 12
           OCTOBER   EQU MAXMONTH-2
           COUNTREG  EQU R5

           CHAPTER   SET  1
           CHAPTER   SET  CHAPTER+1
           CHAPTER   SET  A

<symbol> CODE <expr> | define ROM address
<symbol> DATA <expr> | define direct RAM address
<symbol> IDATA <expr> | define indirect RAM address
<symbol> BIT <expr> | define bit address
<symbol> XDATA <expr> | define external RAM address

These instructions define symbolic addresses for the five 8051 memory segments (address spaces). For DATA, IDATA and BIT type symbols, the value of <expr> must not exceed 0FFH! The value of <expr> must be known on pass 1!
Once defined with one of the above instructions, the symbols cannot be redefined.

Examples:
           EPROM    CODE  08000H
           STACK    DATA       7
           V24BUF   IDATA   080H
           REDLED   BIT     P1.5
           SAMPLER  XDATA  0100H

CSEG [AT <expr>] | switch to CODE segment [at address]
DSEG [AT <expr>] | switch to DATA segment [at address]
ISEG [AT <expr>] | switch to IDATA segment [at address]
BSEG [AT <expr>] | switch to BIT segment [at address]
XSEG [AT <expr>] | switch to XDATA segment [at address]

These instructions switch to one of the five 8051 address spaces. If a segment base address is specified with “AT <expr>”, a new absolute segment is started, and the location counter is set to <expr>. If “AT <expr>” is omitted, the location counter keeps the previous value of the particular segment.
The value of <expr> must be known on pass 1!
At program start, the default segment is CODE and the base addresses and location counters of all segments are set to zero.

Examples:
          DSEG           ;switch to previous DATA segment

          CSEG AT 8000h  ;start a new CODE segment at address 8000H

          XSEG at 0      ;start a new XDATA segment at address 0


Segment Type

III.7 Segment Type

Every assembly time expression is assigned a segment type, depending on its operands and operators. The segment type indicates the address space, the expression result might belong to, if it were used as an address. There are six possible segment types:

CODE
DATA
IDATA
XDATA
BIT
NUMBER     (typeless)

Most expression results have the segment type NUMBER. That means they are assumed to be typeless. However, in some cases it may be useful to assign a particular segment type! The following six rules apply when the segment type is evaluated:

  1. Numerical constants are always typeless.
    Consequently their segment type is NUMBER.
  2. Symbols are assigned a segment type during definition. Symbols that are defined with EQU or SET have no segment type. Labels get the segment type of the currently active segment.
  3. The result of a unary operation (+, -, NOT, HIGH, LOW) will have the segment type of its operand.
  4. The results of all binary operations (except “+”, “-” and “.”) will have no segment type.
  5. If only one operand in a binary “+” or “-” operation has a segment type, then the result will have that segment type, too. In all other cases, the result will have no segment type.
  6. The result of the bit operation “.” will always have the segment type BIT.

Examples:

The following symbols have been defined in a program:
        OFFSET  EQU   16
        START   CODE  30H
        DOIT    CODE  0100H
        REDLED  BIT   P1.3
        VARIAB4 DATA  20H
        PORT    DATA  0C8H
        RELAY   EQU   5
1.) | The expression | START+OFFSET+3 | will have the segment type CODE.
2.) | The expression | START+DOIT | will be typeless.
3.) | The expression | DOIT-REDLED | will be typeless.
4.) | The expression | 2*VARIAB4 | will be typeless.
5.) | The expression | PORT.RELAY | will have the segment type BIT.

The segment type is checked, when expressions appear as addresses. If the expression result is not typeless and does not have the segment type of the corresponding segment, the instruction is flagged with an error message.
The only exceptions are the segment types DATA and IDATA, which are assumed to be compatible in the address range of 0 to 7FH. Since ASEM-51 does only support absolute segments, those addresses are really always pointing to the same physical location in the internal memory.

Example:

Line  I  Addr  Code            Source

   1:          N        30             DSEG AT 030H     ;internal RAM
   2:      30  N        01     COUNT:  DS 1             ;counter variable
   3:
   4:                                  CSEG             ;ROM
   5:    0000  C2 30           START:  CLR COUNT
                                                ^
                         @@@@@ segment type mismatch @@@@@

The CLR instruction is flagged with the error message “segment type mismatch” in the assembler list file, because only a BIT type address is allowed here. However, COUNT is a label with the segment type DATA!


Assembler Controls

III.8 Assembler Controls

ASEM-51 implements a number of assembler controls that influence the assembly process and list file generation. There are two groups of controls: primary and general controls.
Primary controls can only be used at the beginning of the program and remain in effect throughout the assembly. They may be preceded only by control statements, blank and commentary lines. If the same primary control is used multiple times with different parameters, the last one counts.
General controls may be used everywhere in the program. They perform a single action, or remain in effect until they are cancelled or changed by a subsequent control statement.
A control statement starts always with a '$' character, followed by one or more assembler controls.
Assembler controls may have a number or string type operand, which must always be enclosed in parentheses.
Number type operands are arithmetic expressions that must be known on pass 1. String type operands are character strings which are enclosed in parentheses instead of quotes. In analogy to quoted strings, no control characters (including tabs) are allowed within these strings! The string delimiter ')' can be represented by two subsequent ')' characters.
If a control statement changes the listing mode, the control statement itself is always listed in the previous listing mode!
The following table lists all the implemented controls and their abbreviations:

Control | Type | Default | Abbreviation | Meaning
$COND $NOCOND $CONDONLY | G G G | $COND | --- --- --- | list full IFxx .. ENDIF constructions don't list lines in false branches list assembled lines only
$DATE(string) | P | '' | $DA | inserts date string into page header
$DEBUG $NODEBUG | P P | $NODEBUG | $DB $NODB | include debug information into object don't include debug information
$EJECT | G |  | $EJ | start a new page in list file
$ERROR(string) $WARNING(string) | G G |  | --- --- | force a user-defined error output a warning message to console
$GEN $NOGEN $GENONLY | G G G | $GEN | $GE $NOGE $GO | list macro calls and expansion lines list macro calls only list expansion lines only
$INCLUDE(file) | G |  | $IC | include a source file
$LIST $NOLIST | G G | $LIST | $LI $NOLI | list subsequent source lines don't list subsequent source lines
$MACRO(n) $NOMACRO | P P | $MACRO(50) | $MR $NOMR | reserve n % of free memory for macros reserve all for the symbol table
$MOD51 $NOMOD51 | P P | $MOD51 | $MO $NOMO | enable predefined SFR symbols disable predefined SFR symbols
$NOBUILTIN | P | list SFR | --- | don't list predefined symbols
$NOTABS | P | use tabs | --- | don't use tabs in list file
$PAGING $NOPAGING | P P | $PAGING | $PI $NOPI | enable listing page formatting disable listing page formatting
$PAGELENGTH(n) | P | n=64 | $PL | set lines per page for listing
$PAGEWIDTH(n) | P | n=132 | $PW | set columns per line for listing
$PHILIPS | P | MCS-51 | --- | switch on 83C75x family support
$SAVE $RESTORE | G G |  | $SA $RS | save current $LIST/$GEN/$COND state restore old $LIST/$GEN/$COND state
$SYMBOLS $NOSYMBOLS | P P | $SYMBOLS | $SB $NOSB | create symbol table don't create symbol table
$TITLE(string) | G | copyright | $TT | inserts title string into page header
$XREF $NOXREF | P P | $NOXREF | $XR $NOXR | create cross reference don't create cross reference

The subsequent paragraphs contain detailed explanations of the implemented controls.

  1. Primary Controls
  2. General Controls


Primary Controls

III.8.1 Primary Controls

$DATE (string) | Inserts a date string into the list file page header. If $DATE() is specified, the actual date is inserted. Date strings will be truncated to a maximum length of 11 characters. Default is: no date string. The control has no effect, when the $NOPAGING control has been specified.
$DEBUG | Includes debug information into the OMF-51 module. When generating Intel-HEX file output, $DEBUG has no effect.
$NODEBUG | Don't include debug information. (Default!)
$MACRO (n) | Save macro definitions and expand macro calls. (Default!) Optionally reserve n % of free memory for macro definitions. (0 <= n <= 100) Default is n=50. The control has been implemented for compatibility purposes only. In ASEM-51 it has no effect except that it cancels the $NOMACRO control.
$NOMACRO | Don't save macro definitions and don't expand macro calls. Reserve all free memory for the symbol table. The control has been implemented for compatibility purposes only. In ASEM-51, it only suppresses the macro expansion.
$MOD51 | Switches on the built-in 8051 special function register and interrupt symbol definitions. (Default!)
$NOMOD51 | Switches off the built-in 8051 special function register and interrupt symbol definitions. The predefined symbols ??ASEM_51 and ??VERSION cannot be switched off!
$PAGING | Switches on the page formatting in the list file. (Default!)
$NOPAGING | Switches off the page formatting in the list file.
$PAGELENGTH (n) | Sets the list file page length to n lines. (12 <= n <= 65535) Default is n=64. The control has no effect, when the $NOPAGING control has been specified.
$PAGEWIDTH (n) | Sets the list file page width to n columns. (72 <= n <= 255) Default is n=132.
$PHILIPS | Switches on the Philips 83C75x family support option. This disables the LJMP, LCALL, and MOVX instructions as well as the XDATA and XSEG pseudo instructions. Generic jumps and calls will always assemble to absolute addressing.
$SYMBOLS | Generates the symbol table at the end of the list file. (Default!) When the $XREF control is active, $SYMBOLS has no effect!
$NOSYMBOLS | Suppresses the symbol table at the end of the list file. When the $XREF control is active, $NOSYMBOLS has no effect!
$NOBUILTIN | Suppresses the predefined (built-in) symbols in the symbol table or cross-reference listing for a better survey. Only the user-defined symbols are listed.
$NOTABS | Expands all tab characters in the list file output to blanks.
$XREF | Generates a cross-reference listing instead of a symbol table. Note that this slightly slows down assembly, and consumes about 67 % more memory space!
$NOXREF | Generates a symbol table instead of a cross-reference listing. (Default!)

Examples:

$NOMOD51		;switch off 8051 SFR symbol definitions
$PAGELENGTH(60)		;set page length to 60 lines per page
$PW(80)			;set page width to 80 characters per line
$NOSYMBOLS		;no symbol table required
$NOTABS			;printer doesn't support tab characters
$DATE(2. 8. 95)		;date of latest version
$XREF			;generate a cross-reference listing
$ DEBUG NOPAGING	;include debugging information into OMF-51
            ;modules, and suppress page formatting


General Controls

III.8.2 General Controls

$COND | List full IFxx .. ELSEIFxx .. ELSE .. ENDIF constructions. (Default!) The Control is overridden by $NOLIST.
$NOCOND | Don't list lines in false IFxx .. ELSEIFxx .. ELSE .. ENDIF branches. The Control is overridden by $NOLIST.
$CONDONLY | List lines in true IFxx .. ELSEIFxx .. ELSE .. ENDIF branches only, without the IFxx, ELSEIFxx, ELSE and ENDIF statements itself. The Control is overridden by $NOLIST.
$EJECT | Starts a new page in the list file. The control has no effect, when the $NOPAGING control has been specified.
$ERROR (string) | Forces an assembly error with a user-defined error message. This is intended to support configuration management and can be applied sensefully with conditional assembly only.
$WARNING (string) | Outputs a user-defined warning message to the console, and increments the warning count. This is also intended to ease configuration management.
$GEN | List macro calls and expanded macros. (Default!) The listing fully shows the nesting of macro calls. The Control is overridden by $NOLIST.
$NOGEN | List macro calls only. The expanded macros are not listed. The Control is overridden by $NOLIST.
$GENONLY | List the expanded macro bodies only. Macro calls and EXITM statements are not listed. The Control is overridden by $NOLIST.
$INCLUDE (file) | Includes an external source file into the assembler program just behind the $INCLUDE statement. If the include file has not been specified with an absolute path, and it cannot be found in the default directory, the path specified with the /INCLUDES (Linux: -i) command line option (if present) is searched from left to right, and if it cannot be found there either, the path specified with the environment variable ASEM51INC (if defined) is searched from left to right as well. Include files may be nested to any depth.
$LIST | List source code lines. (Default!)
$NOLIST | Do not list source code lines, provided they do not contain errors, until the next $LIST statement occurs.
$SAVE | Saves the current $LIST/$GEN/$COND state on a $SAVE-stack. $SAVE statements can be nested to any depth.
$RESTORE | Restores a previously saved $LIST/$GEN/$COND state.
$TITLE (string) | Inserts a title string into the list file page header. Titles may be truncated according to the specified (or default) page width. Default: ASEM-51 copyright information. The control has no effect, when the $NOPAGING control has been specified.

Examples:

$NOLIST			;switch off listing
$INCLUDE (8052.MCU)	;include 8052 SFR symbol definition file
$LIST			;switch on listing
$TITLE (Computer-Controlled Combustion Unit for Motorcycles)
$EJ			;new page with new title
$ERROR(invalid configuration: buffer size > external RAM size)
$WARNING(int. RAM doesn't meet minimum stack size requirements)
$SAVE GENONLY CONDONLY	;save old $LIST/$GEN/$COND status, and list
            ;only source lines that are really assembled
$RESTORE		;restore previous listing mode


Predefined Symbols

III.9 Predefined Symbols

For easy access to the 8051 special function register and interrupt addresses, ASEM-51 has a number of predefined (built-in) DATA, BIT and CODE symbols.
These predefined symbols can be switched off with the $NOMOD51 control. For detailed information on symbols and addresses refer to Appendix C. For identification of the assembler and its version number, the following NUMBER type symbols are predefined:
??ASEM_51 = 8051H ASEM-51
??VERSION = 0130H version 1.3
These two symbols can not be switched off!


Conditional Assembly

III.10 Conditional Assembly

Conditional assembly allows to assemble or ignore selected parts of code. This can be used to keep the code for various program variants in a single source, to ease configuration control and maintenance. Conditional assembly is also useful to write fancy macros.
The following fourteen meta instructions have been implemented:

IF     <expr>            ELSEIF     <expr>
IFN    <expr>            ELSEIFN    <expr>
IFDEF  <symbol>          ELSEIFDEF  <symbol>
IFNDEF <symbol>          ELSEIFNDEF <symbol>
IFB    <literal>         ELSEIFB    <literal>
IFNB   <literal>         ELSEIFNB   <literal>
ENDIF                    ELSE

Meta instructions overlay the Intel MCS-51 assembly language, but are not part of it! C programmers may compare them to C preprocessor commands.
In the subsequent text, IFxx is used as a collective name for the IF/IFN/IFDEF/IFNDEF/IFB/IFNB instructions. In analogy ELSEIFxx is used as a collective name for the ELSEIF/ELSEIFN/ELSEIFDEF/ELSEIFNDEF/ELSEIFB/ELSEIFNB instructions (not including ELSE).

  1. General IFxx Construction
  2. IFxx and ELSEIFxx Instructions


General IFxx Construction

III.10.1 General IFxx Construction

Simple IFxx ... ENDIF constructions can be used to assemble a number of enclosed statements only, if a particluar condition is met:

IFxx <condition>
  <statement 1>
  <statement 2>
      .			;assembled if <condition> is TRUE
      .
  <statement n>
ENDIF

The statements 1 through n are assembled if <condition> is TRUE, otherwise they are ignored.

If it should be possible to select two variants of code depending on a particular condition, this can be done with an IFxx .. ELSE .. ENDIF construction. If the <condition> in the IFxx statement is TRUE, then statements 1 to n are assembled and the statements n+1 to n+m are ignored.

IFxx <condition>
  <statement 1>
      .			;assembled if <condition> is TRUE
  <statement n>
ELSE
  <statement n+1>
      .			;assembled if <condition> is FALSE
  <statement n+m>
ENDIF

Should <condition> be FALSE, it is exactly vice versa! That means the statements 1 to n are ignored and the statements n+1 to n+m are assembled. This works also, if the IFxx or ELSE branches contain no statements at all.

Whenever more than two cases have to be distinguished, a corresponding number of ELSEIFxx branches can be inserted between the IFxx and the ELSE branch. In such an IFxx .. ELSEIFxx .. ELSE .. ENDIF construction, only the statements in the branch with the first TRUE condition are assembled. The statements in all other branches are ignored.
If none of the conditions is TRUE, only the statements in the ELSE branch (if any) are assembled.

IFxx <condition 1>
      .			;assembled if <condition 1> is TRUE
      .
ELSEIFxx <condition 2>
      .			;assembled if <condition 1> is FALSE,
      .			;and <condition 2> is TRUE
ELSEIFxx <condition 3>
      .			;assembled if <condition 1> and
      .			;<condition 2> are FALSE, and
      .			;<condition 3> is TRUE
      .
      .
ELSEIFxx <condition n>
      .			;assembled if <condition 1> thru
      .			;<condition n-1> are FALSE and
      .			;<condition n> is TRUE
ELSE
      .			;assembled if <condition 1> thru
      .			;<condition n> are FALSE
ENDIF

IFxx ... ELSEIFxx ... ELSE ... ENDIF constructions may be nested to any depth! The listing mode of those constructions can be set with the $COND, $NOCOND and $CONDONLY controls.


IFxx and ELSEIFxx Instructions

III.10.2 IFxx and ELSEIFxx Instructions

The particular IFxx instructions are working as follows:

IF <expr> | The IF condition is TRUE, if the expression <expr> is not equal to 0. The value of <expr> must be known on pass 1!
IFN <expr> | The IFN condition is TRUE, if the expression <expr> is equal to 0. The value of <expr> must be known on pass 1!
IFDEF <symbol> | The IFDEF condition is TRUE, if the <symbol> is defined in the program. Forward references to <symbol> are not allowed!
IFNDEF <symbol> | The IFNDEF condition is TRUE, if the <symbol> is not defined in the program. Forward references to <symbol> are not allowed!
IFB <literal> | The IFB (if blank) condition is TRUE, if the <literal> is empty. <literal> is a string, enclosed in angle brackets.
IFNB <literal> | The IFNB (if not blank) condition is TRUE, if the <literal> is not empty. <literal> is a string, enclosed in angle brackets.
 | Although the IFB and IFNB statements are valid also outside of macros, they can be applied sensefully in macro bodies only. Usually they are used to decide, whether macro arguments have been left blank, or not.

The corresponding ELSEIFxx instructions are working respectively.

Example 1:

IF .. ELSE .. ENDIF construction
TARGET	EQU 0	;configuration:  1 for application board
        ;--------------  0 for evaluation board
IF TARGET
    ORG 0	;program start address of application board
ELSE
    ORG 8000H	;program start address of evaluation board
ENDIF
Currently the program is configured for the evaluation board version.

Example 2:

IFNDEF .. ELSE .. ENDIF construction
;EVA_537 EQU 0		;symbol undefined: 80C537 application board
            ;symbol defined:   80C537 evaluation board
IFNDEF EVA_537
 CLOCK	EQU 16		;clock frequency of application board
 CSEG AT 0		;program start address of application board
ELSE
 CLOCK	EQU 12		;clock frequency of evaluation board
 CSEG AT 8000H		;program start address of evaluation board
ENDIF
Currently the program is configured for the application board version.

Example 3:

IFB .. ELSE .. ENDIF construction
DECIDE MACRO X, Y
 IFB <X&Y>
    NOP
    NOP
 ELSE
    DB	'&X,&Y'
 ENDIF
ENDM
If the above macro is invoked as follows,
    DECIDE Nonsense
the parameter X will be replaced by “Nonsense” and the parameter Y by a zero length string. Thus the IFB literal becomes <Nonsense>, and the macro will be expanded to:
    DB	'Nonsense,'
If the macro will be invoked without arguments,
    DECIDE
the parameters X and Y will be replaced by zero length strings both, and the IFB literal becomes <>. Thus the macro will be expanded to:
    NOP
    NOP
Macros are explained in detail in chapter “III.11 Macro Processing”.

Example 4:

IFNDEF .. ELSEIF .. ELSEIF .. ELSE .. ENDIF construction

The symbol BAUDRATE serves to define the UART baudrate:
IFNDEF BAUDRATE
    LJMP	AUTOBAUD	;automatic baudrate detection
ELSEIF BAUDRATE EQ 9600
    MOV	TH1, #0FDH	;9600 baud
ELSEIF BAUDRATE EQ 1200
    MOV	TH1, #0E8H	;1200 baud
ELSE
 $ERROR(baudrate not implemented)
ENDIF
If the symbol BAUDRATE is not defined at all, a jump to the label AUTOBAUD is performed.
If the symbol BAUDRATE is defined with one of the legal values 9600 or 1200, timer 1 is initialized accordingly.
If the symbol BAUDRATE is defined with another value, a corresponding user-defined error message is generated.


Macro Processing

III.11 Macro Processing

Macros allow to combine basic assembler instructions to “super commands”. For this, macros are defined as blocks of code, which can be used in a program, wherever it is desired.
However, an advanced macro design with parameters, local symbols and macro operators, combined with conditional assembly, goes far beyond this basic functionality!
With only five keywords (MACRO, REPT, ENDM, EXITM, LOCAL) and some control characters the ASEM-51 macro processor provides a variety of powerful tools. These five meta instructions are not part of the Intel MCS-51 assembly language, but overlay it, as already known from conditional assembly.
There are two sorts of macros: callable macros and repeat blocks.

  1. Simple Callable Macros
  2. Macro Parameters
  3. Repeat Macros
  4. Local Symbols
  5. Macro Operators
  6. Premature End of a Macro Expansion
  7. Nested and Recursive Macro Calls
  8. Nested Macro Definitions
  9. Representation in the List File


Simple Callable Macros

III.11.1 Simple Callable Macros

Macros must first be defined, before they can be called in a program. A simple macro definition consists of the macro name, which can be defined with the keyword MACRO, the macro body, and a final ENDM (end macro) instruction.

   <macro name> MACRO
   <body line 1>
   <body line 2>
       .
       .
   <body line m>
   ENDM

The macro name must be a valid, unique symbol. It cannot be redefined later. Keywords cannot be used as macro names.
The macro body may comprise any number of lines. Body lines may be all kinds of assembler instructions, pseudo instructions, controls, meta instructions, macro calls and even further macro definitions.
The macro body and the whole macro definition is terminated with the ENDM instruction.
Macros must be defined, before they can be called. Forward references to macros are not allowed. Once defined, a macro can be called by its name in the subsequent program as often as desired. Whenever a macro is called, the macro body will be “inserted” into the program and then assembled as normal source lines. This process is called macro expansion.

Example:

 MY_FIRST MACRO		;definition
    MOV	A,#42
    ADD	A,R5
 ENDM

    MY_FIRST	;call
After the call of the macro MY_FIRST, the body lines
    MOV	A,#42
    ADD	A,R5
are inserted into the program and assembled.


Macro Parameters

III.11.2 Macro Parameters

Callable macros may have parameters, to allow more flexible use. The names of the formal parameters are specified in the macro definition behind the keyword MACRO, separated by commas. All parameter names of a macro must be different, valid symbols. Keywords cannot be used as parameter names. Macros may have any number of parameters, as long as they fit on one line. Parameter names are local symbols, which are known within the macro only. Outside the macro they have no meaning!

  <macro name> MACRO <parameter 1>, <parameter 2>, ... ,<parameter n>
  <body line 1>
  <body line 2>
      .
      .
  <body line m>
  ENDM

When called, actual arguments can be passed to the macro. The arguments must be separated by commas. Valid macro arguments are

  1. arbitrary sequences of printable characters, not containing blanks, tabs, commas, or semicolons
  2. quoted strings (in single or double quotes)
  3. single printable characters, preceded by '!' as an escape character
  4. character sequences, enclosed in literal brackets < ... >, which may be arbitrary sequences of valid macro arguments (types 1. - 4.), blanks, commas and semicolons
  5. arbitrary sequences of valid macro arguments (types 1. - 4.)
  6. expressions preceded by a '%' character

Note: The keywords MACRO, EQU, SET, CODE, DATA, IDATA, XDATA, BIT, and the ':' character cannot be passed as the first macro argument, because they always start a symbol definition!
Therefore they must be enclosed in literal brackets < ... >.

During macro expansion, these actual arguments replace the symbols of the corresponding formal parameters, wherever they are recognized in the macro body. The first argument replaces the symbol of the first parameter, the second argument replaces the symbol of the second parameter, and so forth. This is called substitution.
Without special assistance, the assembler will not recognize a parameter symbol if it

  • is part of another symbol
  • is contained in a quoted string
  • appears in commentary

Example 1:

 MY_SECOND MACRO CONSTANT, REGISTER
    MOV	A,#CONSTANT
    ADD	A,REGISTER
 ENDM

    MY_SECOND 42, R5
After calling the macro MY_SECOND, the body lines
    MOV	A,#42
    ADD	A,R5
are inserted into the program, and assembled. The parameter names CONSTANT and REGISTER have been replaced by the macro arguments “42” and “R5”.

The number of arguments, passed to a macro, can be less (but not greater) than the number of its formal parameters. If an argument is omitted, the corresponding formal parameter is replaced by an empty string.
If other arguments than the last ones are to be omitted, they can be represented by commas.

Example 2:

The macro OPTIONAL has eight formal parameters:
 OPTIONAL MACRO P1,P2,P3,P4,P5,P6,P7,P8
      .
      .
    <macro body>
      .
      .
 ENDM
If it is called as follows,
        OPTIONAL 1,2,,,5,6
the formal parameters P1, P2, P5 and P6 are replaced by the arguments 1, 2, 5 and 6 during substitution. The parameters P3, P4, P7 and P8 are replaced by a zero length string.

For more flexible macro design, there must be a possibility to recognize empty macro arguments, and to branch the macro expansion accordingly. This can be performed with conditional assembly, using the IFB and IFNB meta instructions.
(See chapter ”III.10.2 IFxx and ELSEIFxx Instructions”.)


Repeat Macros

III.11.3 Repeat Macros

Repeat macros don't have a macro name, and therefore cannot be called multiple times. They are always expanded immediately after their definition. During expansion, their macro body is repeated n times (0 <= n <= 65535). Repeat macros start with the keyword REPT, followed by an expression, which must be known on pass 1. In analogy to callable macros, there is a macro body, which must be terminated with an ENDM instruction:

REPT <expression>
<body line 1>
<body line 2>
    .
    .
<body line m>
ENDM

The expression value specifies how many times the macro body is to be repeated. Since repeat macros start with the keyword REPT, they are sometimes also called “REPT blocks”.

Example:

    REPT 5
    NOP
    ENDM
This REPT block will expand to five NOP instructions immediately after its definition:
    NOP
    NOP
    NOP
    NOP
    NOP


Local Symbols

III.11.4 Local Symbols

Local symbols are symbols, which are only known within a macro body, but not outside the macro. Symbols that are defined for the whole program, will subsequently be called “global symbols” for better understanding. We are already familiar with a special case of local symbols: formal macro parameters. They appear in the macro definition only. Since they are substituted during macro expansion, we don't have further problems with them. But what happens with symbols that are defined in a macro body?

Example 1:

The following simple macro is intended to read a character from the 8051 UART, and to return it in A:
 RECEIVE MACRO
UARTIN:	JNB	RI,UARTIN
    MOV	A,SBUF
    CLR	RI
 ENDM
This will work only once! If the macro RECEIVE is called multiple times, the label UARTIN will be multiply defined.

This can be solved by simply declaring the symbol UARTIN local. For this, the LOCAL statement has been introduced. After the keyword LOCAL, a list of local symbols can be specified, separated by commas. These symbols will only be valid inside the macro that contains the LOCAL statement. LOCAL statements may only be placed directly after the MACRO or REPT statement, preceding the first body line. They may contain any number of local symbols. The macro body may be preceded by an arbitrary number of LOCAL statements.
Local symbols must be valid symbols, unique within the macro, and different from the formal parameters (if any). Keywords cannot be used as local symbol names. If a local symbol has the same name as a global symbol, the local scope takes precedance during substitution.
When a macro is expanded, its local symbols are always substituted: the formal parameters are replaced by the macro arguments, and the local symbols that have been declared in a LOCAL statement are replaced by unique, global symbol names, which the assembler generates during every expansion. These have always the format ??xxxx, where xxxx is a unique symbol number.

Example 2:

After a redesign of our previous macro RECEIVE using local symbols, it is looking as follows:
 RECEIVE MACRO
 LOCAL UARTIN
UARTIN:	JNB	RI,UARTIN
    MOV	A,SBUF
    CLR	RI
 ENDM
Enhanced as shown above, the macro will work correctly, as often as desired. When RECEIVE is called for the first time, the local symbol UARTIN will be replaced by ??0000,
??0000:	JNB	RI,??0000
    MOV	A,SBUF
    CLR	RI
when it is called for the second time, UARTIN will be replaced by ??0001, and so on:
??0001:	JNB	RI,??0001
    MOV	A,SBUF
    CLR	RI

However, it is recommended not to define global symbols in the format ??xxxx, to avoid name conflicts with substituted local symbols from expanded macros.


Macro Operators

III.11.5 Macro Operators

There are some special control characters, which are very useful for macro definition, call and expansion:

;; | Macro commentary | Normally, comments in body lines are also contained in the expanded lines. If a commentary begins with ';;' however, it is not stored during macro definition. Therefore, it doesn't consume memory space, and appears in the list file in the macro definition only, but not in the expanded lines.
! | Literal operator | If the escape character '!' precedes another printable character in a macro argument, the assembler is forced to treat that character literally. This means it will be passed to the macro, even if it is a control character, while the literal operator itself is removed.
< > | Literal brackets | If a macro argument is intended to contain separation or control characters, it must be enclosed in literal brackets < ... > to pass it to the macro as one argument string, while the outermost pair of brackets is removed. Literal brackets can be nested to any depth.
% | Evaluation | If a macro argument is preceded by the evaluation operator '%', it is interpreted as an expression, which will be evaluated before it is passed to the macro. The actual argument string will not be the expression itself, but a decimal ASCII representation of its value. The expression must be known on pass 1.
& | Substitution | The '&' character separates parameter names (local symbols) from surrounding text. Outside quoted strings and commentary it serves only as a general separation character. This applies always when a local symbol directly precedes or follows another alphanumeric string. Inside quoted strings and commentary, a local symbol must be preceded by '&' if it is to be substituted there. During every macro expansion, the assembler removes exactly one '&' from every sequence of '&' characters. This allows for example, to define a nested macro inside a macro body, which also uses the substitution operator '&': one writes simply '&&'!

Example 1:

The commentary should only be visible in the definition of the macro LICENSE:
 LICENSE MACRO
    DB	'Copyright'  ;;legal stuff
 ENDM
When called, the expanded macro body is looking like this in the list file:
        DB	'Copyright'

Example 2:

    SPECIAL !;
passes a semicolon to the macro SPECIAL as a literal argument. This could also be done with
    SPECIAL <;>

Example 3:

The macro CONST defines a 16-bit constant in ROM:
 CONST MACRO NUMB
    DW	NUMB
 ENDM
If it is called as shown below,
    CONST	0815H+4711-42
the parameter NUMB would be substituted as follows:
    DW	0815H+4711-42
If the same macro argument is preceded by a '%' however,
    CONST	%0815H+4711-42
the substitution will result in:
    DW	6738

Example 4:

During substitution, both arguments of the macro CONCAT should form a seamless symbol name:
 CONCAT MACRO NAM, NUM
    MOV R3,#0
NAM&NUM:DJNZ R3,NAM&NUM
 ENDM
When CONCAT is called as follows,
    CONCAT LABEL, 08
the parameters NAM and NUM are substituted during macro expansion as shown below:
    MOV R3,#0
LABEL08:DJNZ R3,LABEL08


Premature End of a Macro Expansion

III.11.6 Premature End of a Macro Expansion

Sometimes it is useful, if a macro expansion can be terminated, before the end of the macro body is reached. This can be forced with the EXITM (exit macro) instruction. However, this makes sense in conjunction with conditional assembly only.

Example:

 FLEXIBLE MACRO QUANTITY
    DB	'Text'
  IF QUANTITY LE 255
   EXITM
  ENDIF
    DW QUANTITY
 ENDM
The macro FLEXIBLE always has to insert the string 'Text' into the CODE space. After that, it should insert a 16-bit constant only, if the numerical value of the parameter QUANTITY is greater than 255.
Otherwise the macro expansion should be terminated with EXITM before. If the macro is called as follows,
    FLEXIBLE 42
it will be expanded to
    DB	'Text'
in list mode $GENONLY/$CONDONLY.
However, if it is called like this,
    FLEXIBLE 4711
it will be expanded to:
    DB	'Text'
    DW	4711

When a macro expansion is terminated with EXITM, all IFxx constructions that have been opened within the macro body so far, are closed.
Of course macro bodies may also contain control statements. If an include file is inserted into a macro body with a $INCLUDE control, and this include file, or a nested include file, contains an EXITM instruction, all include file levels up to the next macro level are closed at this point, and the expansion of that macro is terminated immediately.


Nested and Recursive Macro Calls

III.11.7 Nested and Recursive Macro Calls

Macro bodies may also contain macro calls, and so may the bodies of those called macros, and so forth.
If a macro call is seen throughout the expansion of a macro, the assembler starts immediately with the expansion of the called macro. For this, its its expanded body lines are simply inserted into the expanded macro body of the calling macro, until the called macro is completely expanded. Then the expansion of the calling macro is continued with the body line following the nested macro call.

Example 1:

 INSIDE MACRO
    SUBB	A,R3
 ENDM

 OUTSIDE MACRO
    MOV	A,#42
    INSIDE
    MOV	R7,A
 ENDM
In the body of the macro OUTSIDE, the macro ISIDE is called. If OUTSIDE is called (and the list mode is set to $GENONLY), one gets something like the following expansion:
        Line  I  Addr  Code		Source

      15+ 1  0000  74 2A		MOV	A,#42
      17+ 2  0002  9B		SUBB	A,R3
      18+ 1  0003  FF		MOV	R7,A

Since macro calls can be nested to any depth (while there is free memory), the macro expansion level is shown in the I-column of the list file. Since macro and include file levels can be nested in arbitrary sequence and depth, the nesting level is counted through all macro and include file levels regardless. For better distinction, the character following the global line number is ':' for include file levels, and '+' for macro levels.

If macros are calling themselves, one speaks of recursive macro calls. In this case, there must be some stop criterion, to prevent the macro of calling itself over and over until the assembler is running out of memory! Here again, conditional assembly is the solution:

Example 2:

The macro COUNTDOWN is to define 16-bit constants from 1 thru n in descending order in ROM. n can be passed to the macro as a parameter:
 COUNTDOWN MACRO DEPTH
  IF DEPTH GT 0
    DW	DEPTH
    COUNTDOWN %DEPTH-1
  ENDIF
 ENDM
If COUNTDOWN is called like this,
    COUNTDOWN 7
something like the following macro expansion results (in list mode $GENONLY/$CONDONLY):
    Line  I  Addr  Code		Source

      16+ 1  0000  00 07		DW	7
      19+ 2  0002  00 06		DW	6
      22+ 3  0004  00 05		DW	5
      25+ 4  0006  00 04		DW	4
      28+ 5  0008  00 03		DW	3
      31+ 6  000A  00 02		DW	2
      34+ 7  000C  00 01		DW	1

After the Dark Ages, when the dust was settling and the sun broke through the gloom, computer science discovered the method of recursive programming. There was no doubt that this was the Solution!
And the computer scientists started to explain this to the students. But it seemed that the students didn't get it. They always complained that recursive calculation of n! is a silly example indeed.
All the scientists felt stronly that there was still something missing. After 10 more years of hard research work, they also found the Problem:

Example 3:

The Towers of Hanoi

There are three vertical sticks on the table. On stick 1 there are n discs with different diameters and a hole in the middle, the smallest disc on top, the biggest on the bottom.

The Towers of Hanoi

The Problem is to transfer the tower of discs from stick 1 to stick 2 with a minimum of moves. But only the topmost disc on a tower may be moved at one time, and no disc may be layed on a smaller disc. Stick 3 may be used for scratch purposes. This is a Solution with ASEM-51 macros:
    ;The Towers of Hanoi

$GENONLY CONDONLY

DISCS	EQU	3	;number of discs

 HANOI MACRO n, SOURCE, DESTINATION, SCRATCH
  IF n > 0
    HANOI %(n-1), SOURCE, SCRATCH, DESTINATION
    ;   move topmost disc from stick &SOURCE to stick &DESTINATION
    HANOI %(n-1), SCRATCH, DESTINATION, SOURCE
  ENDIF
 ENDM

    HANOI DISCS, 1, 2, 3

 END
The recursive macro HANOI generates an instruction manual for the Problem, where the instructions appear as comment lines in the list file. The symbol DISCS must be set to the desired number of discs. If HANOI is called like this,
    HANOI 3, 1, 2, 3
the following “instruction manual” is generated:
       27+ 3       ;   move topmost disc from stick 1 to stick 2
       35+ 2       ;   move topmost disc from stick 1 to stick 3
       44+ 3       ;   move topmost disc from stick 2 to stick 3
       53+ 1       ;   move topmost disc from stick 1 to stick 2
       64+ 3       ;   move topmost disc from stick 3 to stick 1
       72+ 2       ;   move topmost disc from stick 3 to stick 2
       81+ 3       ;   move topmost disc from stick 1 to stick 2
The GENONLY and CONDONLY controls ensure that the table doesn't contain all the macro calls and IF constructions.

Exercise 1:
Modify the macro HANOI so that it is generating a move table in ROM, which could directly be used as an input for an 8051-controlled robot-arm that really plays the game with 3 real sticks and n real discs.
Exercise 2:
Prove that the minimum number of moves is 2n - 1. (smile)


Nested Macro Definitions

III.11.8 Nested Macro Definitions

A macro body may also contain further macro definitions. However, these nested macro definitions aren't valid until the enclosing macro has been expanded! That means, the enclosing macro must have been called, before the nested macros can be called.

Example 1:

A macro, which can be used to define macros with arbitrary names, may look as follows:
 DEFINE MACRO MACNAME
  MACNAME MACRO
    DB	'I am the macro &MACNAME.'
  ENDM
 ENDM
In order not to overload the example with “knowhow”, the nested macro only introduces itself kindly with a suitable character string in ROM. The call
    DEFINE Obiwan
would define the macro
  Obiwan MACRO
    DB	'I am the macro Obiwan.'
  ENDM
and the call
    DEFINE Skywalker
would define the following macro:
  Skywalker MACRO
    DB	'I am the macro Skywalker.'
  ENDM

Example 2:

A macro is to insert a variable number of NOPs into the program. For this, a macro with a nested REPT block seems to be best-suited:
 REPEAT MACRO NOPS
  REPT NOPS
    NOP
  ENDM
 ENDM
The macro call
    REPEAT 4
results in something like that:
        Line  I  Addr  Code		Source

           9+ 1        N      0004	REPT 4
          10+ 1				NOP
          11+ 1				ENDM
          12+ 2  0000  00		NOP
          13+ 2  0001  00		NOP
          14+ 2  0002  00		NOP
          15+ 2  0003  00		NOP


Representation in the List File

III.11.9 Representation in the List File

Sometimes macro expansions tend to produce much more listing lines than resulting code. To list or not to list - that is the question! The requirements to either get a better overall view or more detailed information may vary in different development phases or program sections. To always get the best results, a number of general controls has been introduced, which influence the representation of macro expansions and IFxx constructions in the list file (see chapter ”III.8 Assembler Controls”):

Control | Type | Default | Abbreviation | Meaning
$GEN $NOGEN $GENONLY | G G G | $GEN | $GE $NOGE $GO | list macro calls and expansion lines list macro calls only list expansion lines only
$COND $NOCOND $CONDONLY | G G G | $COND | --- --- --- | list full IFxx .. ENDIF constructions don't list lines in false branches list assembled lines only
$SAVE $RESTORE | G G |  | $SA $RS | save current $LIST/$GEN/$COND state restore old $LIST/$GEN/$COND state


Compatibility with the Intel Assembler

IV. Compatibility with the Intel Assembler

With their cross assembler ASM51, Intel has defined and implemented a suitable assembly language for the MCS-51 family, which has always been the only real standard in the 8051 world.
Unfortunately, Intel has announced the “end of life” of ASM51 (final version 2.3) and all the other Intel MCS-51 development tools to the end of 1993.
The ASEM-51 assembly language is a subset of the Intel standard that guarantees maximum compatibility with existing 8051 assembler sources. It implements all 8051 instruction mnemonics as well as a rich and useful subset of the Intel pseudo instructions and assembler controls.

IV.1 Restrictions

Since ASEM-51 generates an Intel-HEX file (or absolute OMF-51) output instead of relocatable object modules, the whole source code of an 8051 application program has to reside in one single file. Consequently all pseudo instructions that deal with relocatable segments or external or public symbols, have not been implemented:

PUBLIC
EXTRN
SEGMENT
RSEG

Intel-style macros are not supported! (Thus the '%' character can be used in comments.)
Up to now only the following assembler controls and their abbreviations have been implemented:

primary controls abbrev.
general controls abbrev.
Intel-

controls
$DATE (<string>) | $DA
$DEBUG | $DB
$NODEBUG | $NODB
$MACRO (<percent>) | $MR
$NOMACRO | $NOMR
$MOD51 | $MO
$NOMOD51 | $NOMO
$PAGING | $PI
$NOPAGING | $NOPI
$SYMBOLS | $SB
$NOSYMBOLS | $NOSB
$PAGELENGTH (<lines>) | $PL
$PAGEWIDTH (<columns>) | $PW

$EJECT | $EJ
$GEN | $GE
$NOGEN | $NOGE
$GENONLY | $GO
$INCLUDE (<file>) | $IC
$LIST | $LI
$NOLIST | $NOLI
$SAVE | $SA
$RESTORE | $RS
$TITLE (<string>) | $TT
ASEM-51

controls
$NOBUILTIN | -----
$NOTABS | -----
$PHILIPS | -----

$COND | -----
$NOCOND | -----
$CONDONLY | -----
$ERROR (<string>) | -----
$WARNING (<string>) | -----

IV.2 Extensions

Assembler controls need not start in column 1, but may be preceded by any number of blanks and tabs. Primary controls may also be preceded by comment lines and $INCLUDE statements, provided the corresponding include files are only containing other control statements and commentary.
The source file may contain blank and comment lines behind the END statement. Character strings may also be enclosed in double quotes.
The DATA symbol for the special function register PCON is predefined.
The bit operator '.' is legal in all expressions, not only in those that have to match the segment type BIT.

ASEM-51 introduces a set of meta instructions, which overlay the Intel MCS-51 assembly language, but are not part of it!
The meta instructions IFxx, ELSEIFxx, ELSE, and ENDIF allow conditional assembly, while the meta instructions MACRO, REPT, ENDM, EXITM, and LOCAL (and some control characters) form a powerful macro processing language. For detailed information on meta instructions see chapters ”III.10 Conditional Assembly” and ”III.11 Macro Processing”.

IV.3 Further Differences

To make semantics unique, especially the precedence of unary operators in expressions is slightly different. Furthermore, expressions with a bit operation “.” evaluate to a BIT type result, not to NUMBER. The segment type of symbols that are defined with EQU or SET evaluates always to NUMBER. Otherwise it might be difficult in some cases, to force the definition of typeless symbols. This is described in detail in chapters ”III.4 Expressions” and ”III.7 Segment Type”.
Except in DB instructions, the zero length string constant '' is illegal. The $NOMOD51 control disables also the predefined CODE addresses. The special assembler symbols AR0...AR7 are predefined for bank 0 before the first USING statement occurs.


List File Format

V. List File Format

The ASEM-51 list file format has been designed to give the user as much information about the generated code as possible. Besides the source code listed, there are five basic layout structures in the listing:

  • the page header
  • the file header
  • the line headings
  • the error diagnosis
  • the symbol table or cross-reference listing

Normally, every page of the listing starts with a page header as shown below:

ASEM-51 V1.3              Copyright (c) 2002 by W.W. Heinz               PAGE 1

It identifies the assembler, contains the copyright information and shows the actual page number at the right margin. After the page header, source lines are output in the list file format. When the maximum number of lines per page is reached, another page header is output after a form feed character. If your printer doesn't support form feeds, the page header can be suppressed with the $NOPAGING control. The number of lines per page can be adjusted to the paper format with the $PAGELENGTH control. The width of the page header (and all other lines) can be set with the $PAGEWIDTH control.

The file header appears only on the first page. It identifies the assembler, lists all input and output files and marks the columns for the line headings. A typical file header is looking as shown below:

       MCS-51 Family Macro Assembler   A S E M - 5 1   V 1.3
       =====================================================

        Source File:    demo.a51
        Object File:    demo.hex
        List File:      demo.lst

 Line  I  Addr  Code            Source

Directly after the file header starts the listing of the source code lines. Every source code line is preceded by a line heading. The line heading consists of four columns: line number, include file or macro level, line address, and generated code.
By default the line headings contain tab characters to save disk space. If your printer or file browser doesn't support tabs, they can be expanded to blanks with the $NOTABS control.

The column “Line” contains the global line number. It is not necessarily the local line number within the particular source file, but a global line number that is counted over the main source, all include files, and all macro expansion lines.
Since include files and macros can be nested arbitrarily, the global line number is terminated by a ':' character for the main source and all include file levels, and with a '+' character for macro expansion levels.

The column “I” flags the level of include file or macro nesting. In the main source, this column is empty. The first include file gets level 1. If this include file includes another include file, this one gets level 2, and so on. This is also valid for nested macro calls. If a macro is called in the main source, its expansion lines get level 1. If this macro calls another one, it gets level 2, and so forth.
Include file and macro levels can be nested in any sequence and to any depth!

The column “Addr” shows the start address of the listed line in the currently active segment (8051 address space). All addresses are represented as hex numbers. The addresses in the CODE and XDATA segments are four-digit numbers. Addresses in all other segments are two-digit numbers. For lines that cannot be assigned to a particular segment, the “Addr” field is left blank.

The “Code” column may contain up to four bytes of generated code, which is sufficient for all 8051 instructions. The code is listed in hex byte quantities starting from the left margin of the “Code” column. However, the code generated for DB and DW instructions may be longer than four bytes. In these cases, the source code line is followed by additional line headings until the whole code of the line is listed.
The “Code” column does not always contain code that consumes space in the 8051 CODE segment. In contrast to many other assemblers, ASEM-51 lists the evaluation results of all expressions that may appear in pseudo instructions or assembler controls. These values are listed in hex representation at the right margin of the “Code” column. The segment type of those expressions is flagged with one single character at the left margin of the “Code” column:

            C         CODE
            D         DATA
            I         IDATA
            X         XDATA
            B         BIT
            N         typeless number
            R         register

The “Source” column finally contains the original source code line. A typical source code listing is looking as follows:

 Line  I  Addr  Code            Source

    1:                                  ;A sample List File Demo Program
    2:                                  ;-------------------------------
    3:                          $NOMOD51                 ;no 8051 SFR
    4:          N      004F     $PAGEWIDTH (79)          ;79 columns per line
    5:                          $NOTABS                  ;expand tabs
    6:          N        90             P1    DATA 090H  ;port 1 address
    7:          B        93             INPUT BIT  P1.3  ;pulse input
    8:
    9:          N      8000             ORG  08000H      ;set location counter
   10:    8000  80 20                   SJMP START       ;jump to start address
   11:
   12:    8002  01 07                   DB  1,7          ;define bytes
   13:    8004  00 02 00 0C             DW  2,12,9       ;define words
          8008  00 09
   14:    800A  63 6F 66 66             DB  'coffeeright (c) 2002',0    ;string
          800E  65 65 72 69
          8012  67 68 74 20
          8016  28 63 29 20
          801A  32 30 30 32
          801E  00
   15:    801F  N      0003             DS  3            ;define space
   16:
   17:    8022  75 30 00        START:  MOV COUNT,#0     ;reset counter
   18:    8025  30 93 FD        LLEVEL: JNB INPUT,LLEVEL ;wait for high
   19:    8028  20 93 FD        HLEVEL: JB  INPUT,HLEVEL ;wait for low
   20:    802B  05 30                   INC COUNT        ;count pulse
   21:    802D  80 F6                   JMP LLEVEL       ;next pulse
   22:
   23:          N        30             DSEG AT 030H     ;internal RAM
   24:      30  N        01     COUNT:  DS 1             ;counter variable
   25:
   26:                                  END

If an error is detected in a source line, its position is flagged with a ^ character as good as possible, and a comprehensive error message is inserted. This is looking as shown below:

   17:    8022  75 30 00        START:  MOV COUNT,#0     ;reset counter
   18:    8025  30 93 FD        LLEVEL: JNB INPUT,LLEVEL ;wait for high
   19:    8028  20 93 00        HLEVEL: JB  INPUT,HLEUEL ;wait for low
                                                  ^
                          @@@@@ symbol not defined @@@@@

   20:    802B  05 30                   INC COUNT        ;count pulse
   21:    802D  80 F6                   JMP LLEVEL       ;next pulse

The error diagnosis at the end of program lists the register banks used, and the total number of errors detected throughout the assembly:

                register banks used:  0, 1, 3

                187 errors detected

A register bank counts as “used”, if the program had switched to that bank with a USING instruction, or one of the special assembler symbols AR0 ... AR7 has been used, while the bank was active. The message

                register banks used:  ---

means, that no bank has been used explicitly, and that the program code may, but need not, be register bank independent.

After the source code listing and error diagnosis, the symbol table or cross-reference listing starts. By default, a symbol table is generated. The symbol table lists all the symbols of a program in alphabetical order with their symbol name, segment type, hex value and first definition line. Predefined symbols are listed without a definition line number.
The symbol table listing can be suppressed with the $NOSYMBOLS control. A typical symbol table listing is looking as shown below:

               L I S T   O F   S Y M B O L S
               =============================

SYMBOL                            TYPE     VALUE        LINE
------------------------------------------------------------
AKKUM                             REGISTER     A          38
COUNT                             DATA        30          47
HLEVEL                            CODE      802E          35
INPUT                             BIT         93          12
LLEVEL                            CODE      802B          34
MY_PROGRAM                        MODULE                  14
P1                                DATA        90
QUANT                             NUMBER    0013          22
RECEIVE                           MACRO                    5
SP                                DATA        81
STACK                             IDATA       80          17
START                             CODE      8022          31
VOLTDC                            XDATA     D785          50

If the $XREF control is specified, a cross-reference listing is generated instead of a symbol table. The corresponding cross-reference listing for the symbol table above is looking as follows:

               C R O S S - R E F E R E N C E - L I S T I N G
               =============================================

SYMBOL                           TYPE     VALUE     DEFINED  REFERENCED
-------------------------------------------------------------------------------
AKKUM                            REGISTER     A          38          42      43
COUNT                            DATA        30          47          32      40
                                                                     43      44
HLEVEL                           CODE      802E          35          35
INPUT                            BIT         93          12          34      35
LLEVEL                           CODE      802B          34          34      41
MY_PROGRAM                       MODULE                  14
P1                               DATA        90                      12
QUANT                            NUMBER    0007          22          44
                                 NUMBER    0013          37
RECEIVE                          MACRO                    5
SP                               DATA        81                      31
STACK                            IDATA       80          17          31
START                            CODE      8022          31          24
TRASH                            undef.    ----                      42
VOLTDC                           XDATA     D785          50          33

It lists all the symbols of the program in alphabetical order, with their symbol name, all definitions including definition lines, segment types, and numerical values. Furthermore, all symbol references are listed as well. The SYMBOL column contains the symbol name, while the columns TYPE, VALUE, and DEFINED may contain the segment types, numerical values, and definition lines of one, more, or no symbol defintions.
Register symbols have the symbol type “REGISTER”, module names have the symbol type “MODULE”, macro names have the symbol type “MACRO”, and symbols that have been referenced but not defined, are flagged with “undef.” in the TYPE column. Starting from column REFERENCED up to the right margin, there is a number of columns (depending on the page width), containing all line numbers of symbol references (if any).
The cross-reference listing does not distinguish, whether multiple definitions of, or references to a particular symbol are legal or not. For this, refer to the error messages in the source listing.


Support of 8051 Derivatives

VI. Support of 8051 Derivatives

Today a large number of 8051 derivatives is available that grows almost monthly! They all use the same instruction set of the MCS-51 processor core, but are different in peripheral components, to cover a wide range of applications. The difference for the assembly language programmer is mainly the varying set of special function registers and interrupt addresses. It is always good practice to use the same SFR names in a microcontroller application program that the manufacturer of the derivative used has defined. For this the processor definition files *.MCU are provided. They all are include files with the special function register definitions of a particular 8051 derivative. However, the predefined symbols of ASEM-51 must be switched off prior to including the SFR definitions of another derivative as shown below:

$NOMOD51
$INCLUDE (80C515.MCU)

This would switch off the predefined symbols of the 8051 and include the register definitions of the 80C515 or 80C535 respectively.
Hence it is easy for the user to adapt ASEM-51 to a brandnew 8051 derivative! All what he has to do is to write a corresponding include file with the SFR definitions derived from the manufacturer's data sheet.
The name of every processor definition file is corresponding to the ROM version of a particular derivative. Of course it also applies to the EPROM, EEPROM, flash, and ROM-less versions (if any) of that derivative.
By the way, the file 8051.MCU provided contains exactly the predefined symbols of ASEM-51, because its internal symbol table has been generated from it!
To switch ASEM-51 to the reduced instruction set of the Philips 83C75x family of microcontrollers, the $PHILIPS control can be used.

Currently the following processor definition files are provided with ASEM-51:

Name | Manufacturer | Versions
8051.MCU | Intel (and others) | 8051, 8031, 8751BH, 8051AH, 8031AH, 8751H, 8051AHP, 8751H-8, 80C51BH, 80C31BH, 87C51, 80C51BHP
 | Atmel | 89C51, 89LV51, 87LV51, 80F51, 87F51
8052.MCU | Intel | 8052AH, 8032AH, 8752BH
 | SIEMENS | 80513, 8352-5
80C52.MCU | Intel | 80C52, 80C32, 87C52, 80C54, 87C54, 80C58, 87C58
83C51FX.MCU | Intel | 83C51FA, 80C51FA, 87C51FA, 83C51FB, 87C51FB, 83C51FC, 87C51FC
83C51R.MCU | Intel | 83C51RA, 80C51RA, 87C51RA, 83C51RB, 87C51RB, 83C51RC, 87C51RC
83C51KB.MCU | Intel | 83C51KB
83C51GB.MCU | Intel | 83C51GB, 80C51GB, 87C51GB
83C151.MCU | Intel | 83C151SB, 87C151SB, 80C151SB, 83C151SA, 87C151SA
83C152.MCU | Intel | 80C152JA, 83C152JA, 80C152JB, 80C152JC, 83C152JC, 80C152JD
83C452.MCU | Intel | 83C452, 80C452
8044.MCU | Intel | 8044AH, 8344AH, 8744AH
83931HA.MCU | Intel | 83931HA, 80931HA
83931AA.MCU | Intel | 83931AA, 80931AA
80512.MCU | SIEMENS | 80512, 80532
80515.MCU | SIEMENS | 80515, 80535, 80515K, 83515-4
80C515.MCU | SIEMENS | 80C515, 80C535, 83C515H
83C515A.MCU | SIEMENS | 83C515A-5, 80C515A
80C517.MCU | SIEMENS | 80C517, 80C537
C501.MCU | Infineon | C501-1R, C501-L
C502.MCU | Infineon | C502-2R, C502-L
C503.MCU | Infineon | C503-1R, C503-L
C504.MCU | Infineon | C504-2R, C504-L
C505.MCU | Infineon | C505-2R, C505-L
C505C.MCU | Infineon | C505C-2R, C505C-L
C505A.MCU | Infineon | C505A-4E, C505A-L
C505CA.MCU | Infineon | C505CA-4E, C505CA-L
C505L.MCU | Infineon | C505L
C508.MCU | Infineon | C508-4R, C508-4E
C509.MCU | Infineon | C509-L
C511.MCU | Infineon | C511, C511A
C513.MCU | Infineon | C513, C513A, C513A-H
C513AO.MCU | Infineon | C513AO
C515.MCU | Infineon | C515-L, C515-1R
C515A.MCU | Infineon | C515A-L, C515A-4R
C515C.MCU | Infineon | C515C-8R
C517A.MCU | Infineon | C517A-L, C517A-4R, 83C517A-5, 80C517A
C540U.MCU | Infineon | C540U
C541U.MCU | Infineon | C541U
C868.MCU | Infineon | C868-1R, C868-1S
83C451.MCU | Philips | 83C451, 80C451, 87C451
83C528.MCU | Philips | 83C528, 80C528, 87C528, 83C524, 87C524, 83CE528, 80CE528, 89CE528
83C550.MCU | Philips | 83C550, 80C550, 87C550
83C552.MCU | Philips | 83C552, 80C552, 87C552
83C562.MCU | Philips | 83C562, 80C562
83C652.MCU | Philips | 83C652, 80C652, 87C652, 83C654, 87C654, 83CE654, 80CE654
83C750.MCU | Philips | 83C750, 87C750
83C751.MCU | Philips | 83C751, 87C751
83C752.MCU | Philips | 83C752, 87C752
83C754.MCU | Philips | 83C754, 87C754
83C851.MCU | Philips | 83C851, 80C851
83C852.MCU | Philips | 83C852
87LPC762.MCU | Philips | 87LPC762
87LPC768.MCU | Philips | 87LPC768
80C32X2.MCU | Philips | 80C31X2, 80C32X2, 80C51X2, 80C52X2, 80C54X2, 80C58X2, 87C51X2, 87C52X2, 87C54X2, 87C58X2, 89C51X2, 89C52X2, 89C54X2, 89C58X2
80C521.MCU | AMD | 80C521, 80C541, 87C521, 87C541, 80C321
80C324.MCU | AMD | 80C324
83C154.MCU | OKI | 83C154, 80C154, 85C154VS
83C154S.MCU | OKI | 83C154S, 80C154S, 85C154HVS
80C310.MCU | DALLAS | 80C310
80C320.MCU | DALLAS | 80C320, 87C320, 80C323, 87C323
80C390.MCU | DALLAS | 80C390
87C520.MCU | DALLAS | 87C520, 83C520
87C530.MCU | DALLAS | 87C530, 83C530
87C550.MCU | DALLAS | 87C550
89C420.MCU | DALLAS | 89C420
DS5000.MCU | DALLAS | 5000FP, 5000, 5000T, 2250, 2250T
DS5001.MCU | DALLAS | 5001FP, 5002FP, 5002FPM, 2251T, 2252T
MAX7651.MCU | Maxim | MAX7651, MAX7652
COM20051.MCU | SMC | COM20051
89C52.MCU | Atmel | 89C52, 89C55, 89LV52, 89LV55, 87LV52, 80F52, 87F52
87F51RC.MCU | Atmel | 87F51RC, 87F55, 87LV55
89C1051.MCU | Atmel | 89C1051
89C2051.MCU | Atmel | 89C2051, 89C4051, 89C1051U
89S8252.MCU | Atmel | 89S8252, 89LS8252
89S51.MCU | Atmel | 89S51
89S52.MCU | Atmel | 89S52, 89LS52
89S53.MCU | Atmel | 89S53, 89LS53
89S4D12.MCU | Atmel | 89S4D12
73M2910.MCU | TDK | 73M2910, 73M2910A
AN2131.MCU | Cypress | AN2121, AN2122, AN2125, AN2126, AN2131, AN2135, AN2136


Appendix A

ASEM-51 Error Messages

A.1 Assembly Errors:

Assembly errors apply to the consistency of the assembly language program in syntax and semantics. If one of these errors is detected, it is flagged in the list file, and program execution continues. When assembly is finished, ASEM terminates with exit code 1:

Error Message | Meaning
address below segment base | Attempt to set the location counter of the current segment below the segment base address.
address out of range | The address of a jump or call instruction cannot be reached with the selected addressing mode.
already a macro parameter | In a macro definition, a local symbol is equal to a previously defined parameter name.
argument exceeds end of line | A macro argument contains more opening than closing angle brackets.
attempt to divide by zero | During evaluation of an assembly time expression, the assembler has to divide by zero.
binary operator expected | In this position of an expression, only binary operators are allowed.
comma expected | There should be a ',' character in the marked position.
commands after END statement | The END statement is followed by further assembler statements.
constant out of range | A numerical constant is greater than 65535.
duplicate local symbol | In a macro definition, a local symbol is defined multiple times or equal to a previously defined parameter name.
duplicate parameter name | The parameter names of a macro are not all different.
ENDIF statement expected | There are pending IFxx constructions, which are not terminated with an ENDIF meta instruction.
ENDM statement expected | There are macro definitions, which are not terminated with an ENDM instruction.
expression out of range | The result of an expression is too big or too small for that purpose.
file name expected | There should be a valid file name in this position.
forward reference to macro | A macro has been called, before it has been defined.
forward reference to register | A register type symbol has been used, before it has been EQU'd or SET.
illegal character | A statement contains characters, which are not allowed in MCS-51 assembly language.
illegal constant | There are syntax errors in a numeric constant.
illegal control statement | A statement is starting with an unknown keyword beginning with a $.
illegal operand | In this position of an expression, a valid operand had been expected.
illegal statement syntax | A statement contains a syntax element, which is not allowed in this context.
invalid base address | A DATA address that is not bit-addressable has been used on the left side of a '.' operator.
invalid bit number | A number greater than 7 has been used on the right side of a '.' operator.
invalid instruction | The instruction has previously been disabled with the $PHILIPS control.
macro type operand | A macro type symbol is used as an operand in a numeric expression.
maximum line length exceeded | During macro expansion, the replacement of parameters and/or local symbols increases the resulting line length to more than 255 characters.
misplaced LOCAL instruction | In a macro definition, a LOCAL instruction is preceded by body lines.
misplaced macro instruction | A macro instruction is used outside of a macro definition, or otherwise misplaced in the program structure.
misplaced macro operator | A macro operator (<, >, !, %, &) has been used in a wrong position.
module name already defined | There are more than one NAME statements in the program.
must be known on first pass | The result of an expression must fully evaluate on pass 1 of assembly.
must be preceded by $SAVE | A $RESTORE control occurs without a preceding $SAVE control.
must be preceded by IFxx | An ELSEIFxx, ELSE or ENDIF meta instruction occurs without a preceding IFxx meta instruction.
no END statement found | The program ends without an END statement.
not allowed in BIT segment | Instruction is not allowed in a BIT segment.
only allowed in BIT segment | Instruction is only allowed in a BIT segment.
only allowed in CODE segment | Instruction is only allowed in a CODE segment.
operand expected | An instruction ends, before it is syntactically complete.
phase error | A symbol is evaluating to different values on pass 1 and pass 2, or a macro has been defined different on pass 1 and pass 2.
Note: | This is a serious, internal assembler error, and should be reported to the author immediately!
preceded by non-control lines | A primary control occurs after statements that are no assembler controls.
register type operand | A register type symbol is used as an operand in a numeric expression.
segment limit exceeded | The location counter exceeds the boundaries of the current segment.
segment type mismatch | The segment type of an operand does not match the type of the instruction.
string exceeds end of line | A character string is not properly terminated with a quote.
symbol already defined | Attempt to redefine a symbol, which is already defined.
symbol name expected | There should be a valid symbol name in this position.
symbol not defined | A symbol is referenced, which has never been defined.
too many closing parentheses | An expression contains more closing than opening parentheses.
too many opening parentheses | An expression contains more opening than closing parentheses.
too many operands | An instruction contains more operands than expected.
unary operator expected | In this position of an expression, only unary operators are allowed.
user-defined error | A user-defined error message has been forced with the $ERROR control.

A.2 Runtime Errors:

Runtime errors are operational errors, or I/O errors. If one of these errors is detected, it is flagged on the console, and ASEM is aborting with exit code 2:

Error Message | Meaning
access denied | No privilege for attempted operation.
ambiguous option name | Not enough characters specified.
argument missing | Option requires an argument.
device or resource busy | Attempt to write to a busy device. (Linux)
disk full | No more free disk space.
disk write-protected | Attempt to write to a write-protected disk.
drive not ready | Disk drive is off, or no media mounted.
duplicate file name | Attempt to overwrite an input or output file.
fatal I/O error | General (unknown) disk or device I/O error.
file not found | Source or include file not found. (DOS/Windows)
illegal option syntax | Option is not correctly specified.
invalid argument | Option has an illegal argument.
no input file | There is no file name in the command line.
no such file or directory | Source or include file not found. (Linux)
not a directory | Path contains a non-directory name. (Linux)
out of memory | Heap overflow!
path not found | Disk or directory not found. (DOS/Windows)
symbol is predefined | A /DEFINE option specifies a predefined symbol.
too many open files | No more free file handles.
too many parameters | More than three file names have been specified.
unknown option | Option is not implemented.

Only DOS command line options are mentioned above for simplification. Under Linux, they have to be replaced by the corresponding Linux options.


Appendix B

HEXBIN Error Messages

B.1 Conversion Errors:

Conversion errors apply to the consistency of Intel-HEX file and program options. If one of these errors is detected, it is flagged on the console, and HEXBIN is aborting with exit code 1:

Error Message | Meaning
checksum error | Checksum is not correct.
data after EOF record | Type 0 records after type 1 record.
file length out of range | /LENGTH option makes file too large.
fill-byte out of range | /FILL option defines byte value > 255.
hex file format error | Certainly no Intel-HEX file.
illegal hex digit | Character is no valid hex digit.
illegal record type | Record type is none of 0 or 1.
invalid record length | Record length doesn't match the record.
multiple EOF records | More than one type 1 record.
no data records found | File doesn't contain any type 0 records.
no EOF record found | File ends without a type 1 record.
offset out of range | /OFFSET option makes file too large.
record exceeds FFFFH | Address space wrap around in record.
record exceeds file length | /LENGTH option made file too short.

Only DOS command line options are mentioned above for simplification. Under Linux, they have to be replaced by the corresponding Linux options.

B.2 Runtime Errors:

Runtime errors are operational errors, or I/O errors. If one of these errors is detected, it is flagged on the console, and HEXBIN is aborting with exit code 2:

Error Message | Meaning
access denied | No privilege for attempted operation.
ambiguous option name | Not enough characters specified.
argument missing | Option requires an argument.
device or resource busy | Attempt to write to a busy device. (Linux)
disk full | No more free disk space.
disk write-protected | Attempt to write to a write-protected disk.
drive not ready | Disk drive is off, or no media mounted.
duplicate file name | Attempt to overwrite an input or output file.
fatal I/O error | General (unknown) disk or device I/O error.
file not found | Intel-HEX file not found. (DOS/Windows)
illegal option syntax | Option is not correctly specified.
invalid argument | Option has an illegal argument.
no input file | There is no file name in the command line.
no such file or directory | Intel-HEX file not found. (Linux)
not a directory | Path contains a non-directory name. (Linux)
path not found | Disk or directory not found. (DOS/Windows)
too many open files | No more free file handles.
too many parameters | More than two file names have been specified.
unknown option | Option is not implemented.


Appendix C

Predefined Symbols

DATA Addresses
P0 | 080H
SP | 081H
DPL | 082H
DPH | 083H
PCON | 087H
TCON | 088H
TMOD | 089H
TL0 | 08AH
TL1 | 08BH
TH0 | 08CH
TH1 | 08DH

P1 | 090H
SCON | 098H
SBUF | 099H
P2 | 0A0H
IE | 0A8H
P3 | 0B0H
IP | 0B8H
PSW | 0D0H
ACC | 0E0H
B | 0F0H

BIT Addresses
IT0 | 088H
IE0 | 089H
IT1 | 08AH
IE1 | 08BH
TR0 | 08CH
TF0 | 08DH
TR1 | 08EH
TF1 | 08FH
RI | 098H
TI | 099H
RB8 | 09AH
TB8 | 09BH
REN | 09CH
SM2 | 09DH
SM1 | 09EH
SM0 | 09FH
EX0 | 0A8H
ET0 | 0A9H
EX1 | 0AAH
ET1 | 0ABH
ES | 0ACH

EA | 0AFH
RXD | 0B0H
TXD | 0B1H
INT0 | 0B2H
INT1 | 0B3H
T0 | 0B4H
T1 | 0B5H
WR | 0B6H
RD | 0B7H
PX0 | 0B8H
PT0 | 0B9H
PX1 | 0BAH
PT1 | 0BBH
PS | 0BCH
P | 0D0H
OV | 0D2H
RS0 | 0D3H
RS1 | 0D4H
F0 | 0D5H
AC | 0D6H
CY | 0D7H

CODE Addresses
RESET | 0000H
EXTI0 | 0003H
TIMER0 | 000BH

EXTI1 | 0013H
TIMER1 | 001BH
SINT | 0023H

Plain Numbers
??ASEM_51 8051H
??VERSION 0130H


Appendix D

Reserved Keywords

Special Assembler Symbols
$ | location counter
A | accumulator
AB | A/B register pair
AR0, AR1, AR2, AR3, AR4, AR5, AR6, AR7 | direct register addresses
C | carry flag
DPTR | data pointer
PC | program counter
R0, R1, R2, R3, R4, R5, R6, R7 | registers

Instruction Mnemonics
ACALL | DA | JNB | MUL | RR
ADD | DEC | JNC | NOP | RRC
ADDC | DIV | JNZ | ORL | SETB
AJMP | DJNZ | JZ | POP | SJMP
ANL | INC | LCALL | PUSH | SUBB
CALL | JB | LJMP | RET | SWAP
CJNE | JBC | MOV | RETI | XCH
CLR | JC | MOVC | RL | XCHD
CPL | JMP | MOVX | RLC | XRL

Pseudo Instructions
AT | DATA | DSEG | IDATA | SET
BIT | DB | DW | ISEG | USING
BSEG | DBIT | END | NAME | XDATA
CODE | DS | EQU | ORG | XSEG
CSEG

Operators
AND | GT | LOW | NE | SHL
EQ | HIGH | LT | NOT | SHR
GE | LE | MOD | OR | XOR

Assembler Controls
$COND | $GO | $NODEBUG | $NOSYMBOLS | $RS
$CONDONLY | $IC | $NOGE | $NOTABS | $SA
$DA | $INCLUDE | $NOGEN | $NOXR | $SAVE
$DATE | $LI | $NOLI | $NOXREF | $SB
$DB | $LIST | $NOLIST | $PAGELENGTH | $SYMBOLS
$DEBUG | $MACRO | $NOMACRO | $PAGEWIDTH | $TITLE
$EJ | $MO | $NOMO | $PAGING | $TT
$EJECT | $MOD51 | $NOMOD51 | $PHILIPS | $WARNING
$ERROR | $MR | $NOMR | $PI | $XR
$GE | $NOBUILTIN | $NOPAGING | $PL | $XREF
$GEN | $NOCOND | $NOPI | $PW
$GENONLY | $NODB | $NOSB | $RESTORE

Meta Instructions
ELSE | ELSEIFN | ENDM | IFDEF | LOCAL
ELSEIF | ELSEIFNB | EXITM | IFN | MACRO
ELSEIFB | ELSEIFNDEF | IF | IFNB | REPT
ELSEIFDEF | ENDIF | IFB | IFNDEF


Appendix E

Specification of the Intel-HEX Format

This object file format is supported by many cross assemblers, utilities, and most EPROM programmers.
An Intel-HEX file is a 7-bit ASCII text file, that contains a sequence of data records and an end record. Every record is a line of text that starts with a colon and ends with CR and LF.
Data records contain up to 16 data bytes, a 16-bit load address, a record type byte and an 8-bit checksum. All numbers are represented by upper case ASCII-hex characters.

DATA RECORD:
    Byte 1               colon (:)
         2 and 3         number of binary data bytes for this record
         4 and 5         load address for this record, high byte
         6 and 7         load address for this record,  low byte
         8 and 9         record type: 00  (data record)
        10 to  x         data bytes, two characters each
       x+1 to  x+2       checksum (two characters)
       x+3 to  x+4       CR and LF
A typical data record looks like
:10E0000002E003E4F588758910F58DF58BD28E302A

The end record is the last line of the file.
In principle it is structured like a data record, but the number of data bytes is 00, the record type is 01 and the load-address field is 0000.

END RECORD:
    Byte 1               colon (:)
         2 and 3         00   (number of data bytes)
         4 and 5         00   (load address, high byte)
         6 and 7         00   (load address, low byte)
         8 and 9         record type: 01  (end record)
        10 and 11        checksum (two characters)
        12 and 13        CR and LF
The typical END record looks like
:00000001FF

The checksum is the two's complement of the 8-bit sum, without carry, of the byte count, the two load address bytes, the record type byte and all data bytes.


Appendix F

The ASCII Character Set

hex | 00 | 10 | 20 | 30 | 40 | 50 | 60 | 70
0 | NUL | DLE |  | 0 | @ | P | ` | p
1 | SOH | DC1 | ! | 1 | A | Q | a | q
2 | STX | DC2 | ” | 2 | B | R | b | r
3 | ETX | DC3 | # | 3 | C | S | c | s
4 | EOT | DC4 | $ | 4 | D | T | d | t
5 | ENQ | NAK | % | 5 | E | U | e | u
6 | ACK | SYN | & | 6 | F | V | f | v
7 | BEL | ETB | ' | 7 | G | W | g | w
8 | BS | CAN | ( | 8 | H | X | h | x
9 | HT | EM | ) | 9 | I | Y | i | y
A | LF | SUB | * | : | J | Z | j | z
B | VT | ESC | + | ; | K | [ | k | {
C | FF | FS | , | < | L | \ | l | |
D | CR | GS | - | = | M | ] | m | }
E | SO | RS | . | > | N | ^ | n | ~
F | SI | US | / | ? | O | _ | o | DEL


Appendix G

Literature

Source | Title | Order Number / Date
Intel MCS® 51 Microcontroller Family User's Manual
MCS-51 Macro Assembler User's Guide
8-Bit Embedded Controllers 1990
8XC51RA/RB/RC CHMOS Single-Chip 8-Bit Microcontroller
8XC51RA/RB/RC Hardware Description, February 1995
83C51KB High Performance Keyboard Microcontroller
83C51KB Hardware Description
MCS 51 Microcontroller Family User's Manual, Feb 1994
8XC151SA and 8XC151SB Hardware Description, June 1996
Embedded Microcontrollers, 1997
8x931AA, 8x931HA USB Peripheral Controller User's Manual

272659-002
272668-001
272800-001
272801-001
272383-002
272832-001
270646-009
Sept. 97
SIEMENS SAB 80512/80532 User's Manual
SAB 80515/80535 User's Manual
SAB 80C515/80C535 Data Sheet
SAB 80C515A/83C515A-5 Addendum
SAB 80C515A/83C515A-5 Data Sheet
SAB 80C517/80C537 User's Manual
SAB 80C517A/83C517A-5 Addendum
SAB 80C517A/83C517A-5 Data Sheet
SIEMENS Microcontrollers Data Catalog
SAB 80513/8352-5 Data Sheet
SAB-C501 User's Manual
SAB-C502 User's Manual
SAB-C503 User's Manual
Application Notes and User Manuals, CD-ROM
C504 8-Bit CMOS Microcontroller User's Manual
C509-L 8-Bit CMOS Microcontroller User's Manual
C515C 8-Bit CMOS Microcontroller User's Manual 		B2-B3808-X-X-7600
B2-B3976-X-X-7600

B158-H6613-X-X-7600
B158-H6605-X-X-7600
B258-B6075-X-X-7600
B158-H6612-X-X-7600
B158-H6581-X-X-7600
B158-H6569-X-X-7600
B158-B6245-X-X-7600
B158-H6723-G1-X-7600
B158-H6722-G1-X-7600
B158-H6650-G1-X-7600
B193-H6900-X-X-7400
B158-H6958-X-X-7600
B158-H6973-X-X-7600
B158-H6981-X-X-7600
Infineon C515 8-Bit CMOS Microcontroller User's Manual
C515A 8-Bit CMOS Microcontroller User's Manual
C517A 8-Bit CMOS Microcontroller User's Manual
C540U/C541U 8-Bit CMOS Microcontroller Data Sheet
C513AO 8-bit CMOS Microcontroller User's Manual
C505/C505C 8-Bit CMOS Microcontroller User's Manual
C505A/C505CA 8-Bit CMOS Microcontroller, Addendum
C505L 8-bit CMOS Microcontroller, Data Sheet
C508 8-Bit CMOS Microcontroller User's Manual
C868 8-Bit CMOS Microcontroller User's Manual, V 0.5.1 		04.98
08.97
01.99
10.97
05.99
08.97
09.97
06.99
May 2001
Jan 2002
Philips PCB83C552 User's Manual
PCB83C552, PCB80C552 Development Data
8051-Based 8-Bit Microcontrollers - Data Handbook
83C754/87C754 Preliminary Specification
87LPC762 Data Sheet
87LPC768 Data Sheet
P80C3xX2, P80C5xX2, P87C5xX2 Data Sheet
P89C51X2/52X2/54X2/58X2 Data Sheet

1994
1998 Apr 23
2001 Oct 26
2002 Mar 12
2002 Jun 12
2002 Jun 05
AMD | Eight-Bit 80C51 Embedded Processors - Data Book | 1990
OKI MSM80C154, MSM83C154 User's Manual
Microcontroller Data Book
5th Edition 1990
TDK | TSC 73M2910/2910A Microcontroller | 10/22/96 - rev.
DALLAS High-Speed Micro User's Guide, V1.3 January 1994
Secure Microcontroller User's Guide
DS80C310 High-Speed Micro
DS80C320/DS80C323 High-Speed/Low-Power Micro
DS80C390 Dual CAN High-Speed Microprocessor
DS87C520/DS83C520 EPROM/ROM High-Speed Micro
DS87C530/DS83C530 EPROM/ROM Micro with Real-Time Clock
DS87C550 EPROM High-Speed Micro with A/D and PWM
DS89C420 Ultra High-Speed Microcontroller User's Guide 		011994
062001
090198
070196
090799
110195
112299
091698
020602
Maxim MAX7651/MAX7652 Programmer's Reference Manual
MAX7651/MAX7652 Data Sheet
19-2119; Rev 0; 8/01
Atmel AT89C51, 8-Bit Microcontroller with 4 Kbytes Flash
AT89C52, 8-Bit Microcontroller with 8 Kbytes Flash
AT89C55, 8 bit Microcontroller with 20K bytes Flash
AT89LV51, 8-Bit Microcontroller with 4 Kbytes Flash
AT89LV52, 8-Bit Microcontroller with 8 Kbytes Flash
AT89C1051, 8-Bit Microcontroller with 1 Kbyte Flash
AT89C2051, 8-Bit Microcontroller with 2 Kbytes Flash
AT89C4051, 8-Bit Microcontroller with 4K Bytes Flash
AT89C1051U, 8-Bit Microcontroller with 1K Bytes Flash
AT89S8252, 8 Bit Microcontroller with 8K bytes Flash
AT89LS8252, 8-Bit Microcontroller with 8K Bytes Flash
AT89S51, 8-bit Microcontroller with 4K Bytes ISP Flash
AT89S52, 8-bit Microcontroller with 8K Bytes ISP Flash
AT89LS52, 8-bit LV Microcontroller with 8K Bytes ISP Flash
AT89S53, 8-Bit Microcontroller with 12K Bytes Flash
AT89LS53, 8-Bit Microcontroller with 12K Bytes Flash
AT89LV55, 8-Bit Microcontroller with 20K bytes Flash
AT80F51, 8-Bit Microcontroller with 4K Bytes QuickFlash
AT87F51, 8-Bit Microcontroller with 4K Bytes QuickFlash
AT80F52, 8-Bit Microcontroller with 8K Bytes QuickFlash
AT87F52, 8-Bit Microcontroller with 8K Bytes QuickFlash
AT89S4D12, 8-Bit Microcontroller with 132K Bytes Flash
AT87F51RC, 8-Bit Microcontroller with 32K Bytes QuickFlash
AT87F55, 8-Bit Microcontroller with 20K Bytes QuickFlash
AT87LV51, 8-bit Microcontroller with 4K Bytes QuickFlash
AT87LV52, 8-Bit Microcontroller with 8K Bytes QuickFlash
AT87LV55, 8-bit Microcontroller with 20K Bytes QuickFlash 		0265E
0313E

0303C

0366C
0368C
Preliminary
Preliminary
Preliminary
0850B-B-12/97
2487A-10/01
1919A-07/01
2601A-12/01
Preliminary
0851B-B-12/97
0811A-A-7/97
0979A-A-12/97
1012A-02/98
0980A-A-12/97
1011A-02/98
0921A-A-12/97
1106B-12/98
1147A-05/99
1602A-04/00
1437A-07/99
1609A-04/00
Cypress | The EZ-USB Integrated Circuit, Technical Reference Manual | Version 1.9

German Literature
Author | Title | Order Number
Andreas Roth | Das Microcontroller Kochbuch MCS51, 6. Aufl. 2002, mitp-Verlag | ISBN 3-8266-0722-8


Appendix H

Trademarks

ASEM-51 is a trademark of W.W. Heinz.
MCS-51 and ASM51 are trademarks of Intel Corporation.
Turbo-Pascal and Borland-Pascal are trademarks of Borland International, Inc.
Delphi is a trademark of Borland International, Inc.
Turbo C++ and Borland C++ are trademarks of Borland International, Inc.
Turbo-Assembler is a trademark of Borland International, Inc.
IBM-PC, IBM-XT, IBM-AT and OS/2 are trademarks of IBM Corporation.
MS-DOS and Windows are trademarks of Microsoft Corporation.
Novell DOS is a trademark of Novell, Inc.
BRIEF is a trademark of SDC Partners II L.P.
4DOS is a registered trademark of JP Software Inc.
Linux is a trademark of Linus Torvalds.
FreePascal is a trademark of Florian Klämpfl.
All device codes of 8051 derivatives are trademarks of the manufacturers.
Other brand and product names are trademarks of their respective holders.


Appendix I

8051 Instructions in numerical Order

Abbreviations: | direct | = | 8-bit DATA address in internal memory
 | const8 | = | 8-bit constant in CODE memory
 | const16 | = | 16-bit constant in CODE memory
 | addr16 | = | 16-bit long CODE address
 | addr11 | = | 11-bit absolute CODE address
 | rel | = | signed 8-bit relative CODE address
 | bit | = | 8-bit BIT address in internal memory

Opcode | Mnemonic | Operands | Bytes | Flags |  |  |  | Cycles
00 | NOP |  | 1 |  |  |  |  | 1
01 | AJMP | addr11 | 2 |  |  |  |  | 2
02 | LJMP | addr16 | 3 |  |  |  |  | 2
03 | RR | A | 1 |  |  |  |  | 1
04 | INC | A | 1 |  |  |  | P | 1
05 | INC | direct | 2 |  |  |  |  | 1
06 | INC | @R0 | 1 |  |  |  |  | 1
07 | INC | @R1 | 1 |  |  |  |  | 1
08 | INC | R0 | 1 |  |  |  |  | 1
09 | INC | R1 | 1 |  |  |  |  | 1
0A | INC | R2 | 1 |  |  |  |  | 1
0B | INC | R3 | 1 |  |  |  |  | 1
0C | INC | R4 | 1 |  |  |  |  | 1
0D | INC | R5 | 1 |  |  |  |  | 1
0E | INC | R6 | 1 |  |  |  |  | 1
0F | INC | R7 | 1 |  |  |  |  | 1
10 | JBC | bit, rel | 3 |  |  |  |  | 2
11 | ACALL | addr11 | 2 |  |  |  |  | 2
12 | LCALL | addr16 | 3 |  |  |  |  | 2
13 | RRC | A | 1 | CY |  |  | P | 1
14 | DEC | A | 1 |  |  |  | P | 1
15 | DEC | direct | 2 |  |  |  |  | 1
16 | DEC | @R0 | 1 |  |  |  |  | 1
17 | DEC | @R1 | 1 |  |  |  |  | 1
18 | DEC | R0 | 1 |  |  |  |  | 1
19 | DEC | R1 | 1 |  |  |  |  | 1
1A | DEC | R2 | 1 |  |  |  |  | 1
1B | DEC | R3 | 1 |  |  |  |  | 1
1C | DEC | R4 | 1 |  |  |  |  | 1
1D | DEC | R5 | 1 |  |  |  |  | 1
1E | DEC | R6 | 1 |  |  |  |  | 1
1F | DEC | R7 | 1 |  |  |  |  | 1
20 | JB | bit, rel | 3 |  |  |  |  | 2
21 | AJMP | addr11 | 2 |  |  |  |  | 2
22 | RET |  | 1 |  |  |  |  | 2
23 | RL | A | 1 |  |  |  |  | 1
24 | ADD | A, #const8 | 2 | CY | AC | OV | P | 1
25 | ADD | A, direct | 2 | CY | AC | OV | P | 1
26 | ADD | A, @R0 | 1 | CY | AC | OV | P | 1
27 | ADD | A, @R1 | 1 | CY | AC | OV | P | 1
28 | ADD | A, R0 | 1 | CY | AC | OV | P | 1
29 | ADD | A, R1 | 1 | CY | AC | OV | P | 1
2A | ADD | A, R2 | 1 | CY | AC | OV | P | 1
2B | ADD | A, R3 | 1 | CY | AC | OV | P | 1
2C | ADD | A, R4 | 1 | CY | AC | OV | P | 1
2D | ADD | A, R5 | 1 | CY | AC | OV | P | 1
2E | ADD | A, R6 | 1 | CY | AC | OV | P | 1
2F | ADD | A, R7 | 1 | CY | AC | OV | P | 1
30 | JNB | bit, rel | 3 |  |  |  |  | 2
31 | ACALL | addr11 | 2 |  |  |  |  | 2
32 | RETI |  | 1 |  |  |  |  | 2
33 | RLC | A | 1 | CY |  |  | P | 1
34 | ADDC | A, #const8 | 2 | CY | AC | OV | P | 1
35 | ADDC | A, direct | 2 | CY | AC | OV | P | 1
36 | ADDC | A, @R0 | 1 | CY | AC | OV | P | 1
37 | ADDC | A, @R1 | 1 | CY | AC | OV | P | 1
38 | ADDC | A, R0 | 1 | CY | AC | OV | P | 1
39 | ADDC | A, R1 | 1 | CY | AC | OV | P | 1
3A | ADDC | A, R2 | 1 | CY | AC | OV | P | 1
3B | ADDC | A, R3 | 1 | CY | AC | OV | P | 1
3C | ADDC | A, R4 | 1 | CY | AC | OV | P | 1
3D | ADDC | A, R5 | 1 | CY | AC | OV | P | 1
3E | ADDC | A, R6 | 1 | CY | AC | OV | P | 1
3F | ADDC | A, R7 | 1 | CY | AC | OV | P | 1
40 | JC | rel | 2 |  |  |  |  | 2
41 | AJMP | addr11 | 2 |  |  |  |  | 2
42 | ORL | direct, A | 2 |  |  |  |  | 1
43 | ORL | direct, #const8 | 3 |  |  |  |  | 2
44 | ORL | A, #const8 | 2 |  |  |  | P | 1
45 | ORL | A, direct | 2 |  |  |  | P | 1
46 | ORL | A, @R0 | 1 |  |  |  | P | 1
47 | ORL | A, @R1 | 1 |  |  |  | P | 1
48 | ORL | A, R0 | 1 |  |  |  | P | 1
49 | ORL | A, R1 | 1 |  |  |  | P | 1
4A | ORL | A, R2 | 1 |  |  |  | P | 1
4B | ORL | A, R3 | 1 |  |  |  | P | 1
4C | ORL | A, R4 | 1 |  |  |  | P | 1
4D | ORL | A, R5 | 1 |  |  |  | P | 1
4E | ORL | A, R6 | 1 |  |  |  | P | 1
4F | ORL | A, R7 | 1 |  |  |  | P | 1
50 | JNC | rel | 2 |  |  |  |  | 2
51 | ACALL | addr11 | 2 |  |  |  |  | 2
52 | ANL | direct, A | 2 |  |  |  |  | 1
53 | ANL | direct, #const8 | 3 |  |  |  |  | 2
54 | ANL | A, #const8 | 2 |  |  |  | P | 1
55 | ANL | A, direct | 2 |  |  |  | P | 1
56 | ANL | A, @R0 | 1 |  |  |  | P | 1
57 | ANL | A, @R1 | 1 |  |  |  | P | 1
58 | ANL | A, R0 | 1 |  |  |  | P | 1
59 | ANL | A, R1 | 1 |  |  |  | P | 1
5A | ANL | A, R2 | 1 |  |  |  | P | 1
5B | ANL | A, R3 | 1 |  |  |  | P | 1
5C | ANL | A, R4 | 1 |  |  |  | P | 1
5D | ANL | A, R5 | 1 |  |  |  | P | 1
5E | ANL | A, R6 | 1 |  |  |  | P | 1
5F | ANL | A, R7 | 1 |  |  |  | P | 1
60 | JZ | rel | 2 |  |  |  |  | 2
61 | AJMP | addr11 | 2 |  |  |  |  | 2
62 | XRL | direct, A | 2 |  |  |  |  | 1
63 | XRL | direct, #const8 | 3 |  |  |  |  | 2
64 | XRL | A, #const8 | 2 |  |  |  | P | 1
65 | XRL | A, direct | 2 |  |  |  | P | 1
66 | XRL | A, @R0 | 1 |  |  |  | P | 1
67 | XRL | A, @R1 | 1 |  |  |  | P | 1
68 | XRL | A, R0 | 1 |  |  |  | P | 1
69 | XRL | A, R1 | 1 |  |  |  | P | 1
6A | XRL | A, R2 | 1 |  |  |  | P | 1
6B | XRL | A, R3 | 1 |  |  |  | P | 1
6C | XRL | A, R4 | 1 |  |  |  | P | 1
6D | XRL | A, R5 | 1 |  |  |  | P | 1
6E | XRL | A, R6 | 1 |  |  |  | P | 1
6F | XRL | A, R7 | 1 |  |  |  | P | 1
70 | JNZ | rel | 2 |  |  |  |  | 2
71 | ACALL | addr11 | 2 |  |  |  |  | 2
72 | ORL | C, bit | 2 | CY |  |  |  | 2
73 | JMP | @A+DPTR | 1 |  |  |  |  | 2
74 | MOV | A, #const8 | 2 |  |  |  | P | 1
75 | MOV | direct, #const8 | 3 |  |  |  |  | 2
76 | MOV | @R0, #const8 | 2 |  |  |  |  | 1
77 | MOV | @R1, #const8 | 2 |  |  |  |  | 1
78 | MOV | R0, #const8 | 2 |  |  |  |  | 1
79 | MOV | R1, #const8 | 2 |  |  |  |  | 1
7A | MOV | R2, #const8 | 2 |  |  |  |  | 1
7B | MOV | R3, #const8 | 2 |  |  |  |  | 1
7C | MOV | R4, #const8 | 2 |  |  |  |  | 1
7D | MOV | R5, #const8 | 2 |  |  |  |  | 1
7E | MOV | R6, #const8 | 2 |  |  |  |  | 1
7F | MOV | R7, #const8 | 2 |  |  |  |  | 1
80 | SJMP | rel | 2 |  |  |  |  | 2
81 | AJMP | addr11 | 2 |  |  |  |  | 2
82 | ANL | C, bit | 2 | CY |  |  |  | 2
83 | MOVC | A, @A+PC | 1 |  |  |  | P | 2
84 | DIV | AB | 1 | CY |  | OV | P | 4
85 | MOV | direct, direct | 3 |  |  |  |  | 2
86 | MOV | direct, @R0 | 2 |  |  |  |  | 2
87 | MOV | direct, @R1 | 2 |  |  |  |  | 2
88 | MOV | direct, R0 | 2 |  |  |  |  | 2
89 | MOV | direct, R1 | 2 |  |  |  |  | 2
8A | MOV | direct, R2 | 2 |  |  |  |  | 2
8B | MOV | direct, R3 | 2 |  |  |  |  | 2
8C | MOV | direct, R4 | 2 |  |  |  |  | 2
8D | MOV | direct, R5 | 2 |  |  |  |  | 2
8E | MOV | direct, R6 | 2 |  |  |  |  | 2
8F | MOV | direct, R7 | 2 |  |  |  |  | 2
90 | MOV | DPTR, #const16 | 3 |  |  |  |  | 2
91 | ACALL | addr11 | 2 |  |  |  |  | 2
92 | MOV | bit, C | 2 |  |  |  |  | 2
93 | MOVC | A, @A+DPTR | 1 |  |  |  | P | 2
94 | SUBB | A, #const8 | 2 | CY | AC | OV | P | 1
95 | SUBB | A, direct | 2 | CY | AC | OV | P | 1
96 | SUBB | A, @R0 | 1 | CY | AC | OV | P | 1
97 | SUBB | A, @R1 | 1 | CY | AC | OV | P | 1
98 | SUBB | A, R0 | 1 | CY | AC | OV | P | 1
99 | SUBB | A, R1 | 1 | CY | AC | OV | P | 1
9A | SUBB | A, R2 | 1 | CY | AC | OV | P | 1
9B | SUBB | A, R3 | 1 | CY | AC | OV | P | 1
9C | SUBB | A, R4 | 1 | CY | AC | OV | P | 1
9D | SUBB | A, R5 | 1 | CY | AC | OV | P | 1
9E | SUBB | A, R6 | 1 | CY | AC | OV | P | 1
9F | SUBB | A, R7 | 1 | CY | AC | OV | P | 1
A0 | ORL | C, /bit | 2 | CY |  |  |  | 2
A1 | AJMP | addr11 | 2 |  |  |  |  | 2
A2 | MOV | C, bit | 2 | CY |  |  |  | 1
A3 | INC | DPTR | 1 |  |  |  |  | 2
A4 | MUL | AB | 1 | CY |  | OV | P | 4
A5 | illegal opcode
A6 | MOV | @R0, direct | 2 |  |  |  |  | 2
A7 | MOV | @R1, direct | 2 |  |  |  |  | 2
A8 | MOV | R0, direct | 2 |  |  |  |  | 2
A9 | MOV | R1, direct | 2 |  |  |  |  | 2
AA | MOV | R2, direct | 2 |  |  |  |  | 2
AB | MOV | R3, direct | 2 |  |  |  |  | 2
AC | MOV | R4, direct | 2 |  |  |  |  | 2
AD | MOV | R5, direct | 2 |  |  |  |  | 2
AE | MOV | R6, direct | 2 |  |  |  |  | 2
AF | MOV | R7, direct | 2 |  |  |  |  | 2
B0 | ANL | C, /bit | 2 | CY |  |  |  | 2
B1 | ACALL | addr11 | 2 |  |  |  |  | 2
B2 | CPL | bit | 2 |  |  |  |  | 1
B3 | CPL | C | 1 | CY |  |  |  | 1
B4 | CJNE | A, #const8, rel | 3 | CY |  |  |  | 2
B5 | CJNE | A, direct, rel | 3 | CY |  |  |  | 2
B6 | CJNE | @R0, #const8, rel | 3 | CY |  |  |  | 2
B7 | CJNE | @R1, #const8, rel | 3 | CY |  |  |  | 2
B8 | CJNE | R0, #const8, rel | 3 | CY |  |  |  | 2
B9 | CJNE | R1, #const8, rel | 3 | CY |  |  |  | 2
BA | CJNE | R2, #const8, rel | 3 | CY |  |  |  | 2
BB | CJNE | R3, #const8, rel | 3 | CY |  |  |  | 2
BC | CJNE | R4, #const8, rel | 3 | CY |  |  |  | 2
BD | CJNE | R5, #const8, rel | 3 | CY |  |  |  | 2
BE | CJNE | R6, #const8, rel | 3 | CY |  |  |  | 2
BF | CJNE | R7, #const8, rel | 3 | CY |  |  |  | 2
C0 | PUSH | direct | 2 |  |  |  |  | 2
C1 | AJMP | addr11 | 2 |  |  |  |  | 2
C2 | CLR | bit | 2 |  |  |  |  | 1
C3 | CLR | C | 1 | CY |  |  |  | 1
C4 | SWAP | A | 1 |  |  |  |  | 1
C5 | XCH | A, direct | 2 |  |  |  | P | 1
C6 | XCH | A, @R0 | 1 |  |  |  | P | 1
C7 | XCH | A, @R1 | 1 |  |  |  | P | 1
C8 | XCH | A, R0 | 1 |  |  |  | P | 1
C9 | XCH | A, R1 | 1 |  |  |  | P | 1
CA | XCH | A, R2 | 1 |  |  |  | P | 1
CB | XCH | A, R3 | 1 |  |  |  | P | 1
CC | XCH | A, R4 | 1 |  |  |  | P | 1
CD | XCH | A, R5 | 1 |  |  |  | P | 1
CE | XCH | A, R6 | 1 |  |  |  | P | 1
CF | XCH | A, R7 | 1 |  |  |  | P | 1
D0 | POP | direct | 2 |  |  |  |  | 2
D1 | ACALL | addr11 | 2 |  |  |  |  | 2
D2 | SETB | bit | 2 |  |  |  |  | 1
D3 | SETB | C | 1 | CY |  |  |  | 1
D4 | DA | A | 1 | CY |  |  | P | 1
D5 | DJNZ | direct, rel | 3 |  |  |  |  | 2
D6 | XCHD | A, @R0 | 1 |  |  |  | P | 1
D7 | XCHD | A, @R1 | 1 |  |  |  | P | 1
D8 | DJNZ | R0, rel | 2 |  |  |  |  | 2
D9 | DJNZ | R1, rel | 2 |  |  |  |  | 2
DA | DJNZ | R2, rel | 2 |  |  |  |  | 2
DB | DJNZ | R3, rel | 2 |  |  |  |  | 2
DC | DJNZ | R4, rel | 2 |  |  |  |  | 2
DD | DJNZ | R5, rel | 2 |  |  |  |  | 2
DE | DJNZ | R6, rel | 2 |  |  |  |  | 2
DF | DJNZ | R7, rel | 2 |  |  |  |  | 2
E0 | MOVX | A, @DPTR | 1 |  |  |  | P | 2
E1 | AJMP | addr11 | 2 |  |  |  |  | 2
E2 | MOVX | A, @R0 | 1 |  |  |  | P | 2
E3 | MOVX | A, @R1 | 1 |  |  |  | P | 2
E4 | CLR | A | 1 |  |  |  | P | 1
E5 | MOV | A, direct | 2 |  |  |  | P | 1
E6 | MOV | A, @R0 | 1 |  |  |  | P | 1
E7 | MOV | A, @R1 | 1 |  |  |  | P | 1
E8 | MOV | A, R0 | 1 |  |  |  | P | 1
E9 | MOV | A, R1 | 1 |  |  |  | P | 1
EA | MOV | A, R2 | 1 |  |  |  | P | 1
EB | MOV | A, R3 | 1 |  |  |  | P | 1
EC | MOV | A, R4 | 1 |  |  |  | P | 1
ED | MOV | A, R5 | 1 |  |  |  | P | 1
EE | MOV | A, R6 | 1 |  |  |  | P | 1
EF | MOV | A, R7 | 1 |  |  |  | P | 1
F0 | MOVX | @DPTR, A | 1 |  |  |  |  | 2
F1 | ACALL | addr11 | 2 |  |  |  |  | 2
F2 | MOVX | @R0, A | 1 |  |  |  |  | 2
F3 | MOVX | @R1, A | 1 |  |  |  |  | 2
F4 | CPL | A | 1 |  |  |  | P | 1
F5 | MOV | direct, A | 2 |  |  |  |  | 1
F6 | MOV | @R0, A | 1 |  |  |  |  | 1
F7 | MOV | @R1, A | 1 |  |  |  |  | 1
F8 | MOV | R0, A | 1 |  |  |  |  | 1
F9 | MOV | R1, A | 1 |  |  |  |  | 1
FA | MOV | R2, A | 1 |  |  |  |  | 1
FB | MOV | R3, A | 1 |  |  |  |  | 1
FC | MOV | R4, A | 1 |  |  |  |  | 1
FD | MOV | R5, A | 1 |  |  |  |  | 1
FE | MOV | R6, A | 1 |  |  |  |  | 1
FF | MOV | R7, A | 1 |  |  |  |  | 1


Appendix J

8051 Instructions in lexical Order

Abbreviations:
direct | = | 8-bit DATA address in internal memory
const8 | = | 8-bit constant in CODE memory
const16 | = | 16-bit constant in CODE memory
addr16 | = | 16-bit long CODE address
addr11 | = | 11-bit absolute CODE address
rel | = | signed 8-bit relative CODE address
bit | = | 8-bit BIT address in internal memory
i | = | register numbers 0 or 1
n | = | register numbers 0 thru 7
a | = | 32 * m
m | = | the 3 most significant bits of an absolute address

Opcode | Mnemonic | Operands | Bytes | Flags |  |  |  | Cycles
11 + a | ACALL | addr11 | 2 |  |  |  |  | 2
24 | ADD | A, #const8 | 2 | CY | AC | OV | P | 1
26 + i | ADD | A, @Ri | 1 | CY | AC | OV | P | 1
25 | ADD | A, direct | 2 | CY | AC | OV | P | 1
28 + n | ADD | A, Rn | 1 | CY | AC | OV | P | 1
34 | ADDC | A, #const8 | 2 | CY | AC | OV | P | 1
36 + i | ADDC | A, @Ri | 1 | CY | AC | OV | P | 1
35 | ADDC | A, direct | 2 | CY | AC | OV | P | 1
38 + n | ADDC | A, Rn | 1 | CY | AC | OV | P | 1
01 + a | AJMP | addr11 | 2 |  |  |  |  | 2
54 | ANL | A, #const8 | 2 |  |  |  | P | 1
56 + i | ANL | A, @Ri | 1 |  |  |  | P | 1
55 | ANL | A, direct | 2 |  |  |  | P | 1
58 + n | ANL | A, Rn | 1 |  |  |  | P | 1
B0 | ANL | C, /bit | 2 | CY |  |  |  | 2
82 | ANL | C, bit | 2 | CY |  |  |  | 2
53 | ANL | direct, #const8 | 3 |  |  |  |  | 2
52 | ANL | direct, A | 2 |  |  |  |  | 1
B6 + i | CJNE | @Ri, #const8, rel | 3 | CY |  |  |  | 2
B4 | CJNE | A, #const8, rel | 3 | CY |  |  |  | 2
B5 | CJNE | A, direct, rel | 3 | CY |  |  |  | 2
B8 + n | CJNE | Rn, #const8, rel | 3 | CY |  |  |  | 2
E4 | CLR | A | 1 |  |  |  | P | 1
C2 | CLR | bit | 2 |  |  |  |  | 1
C3 | CLR | C | 1 | CY |  |  |  | 1
F4 | CPL | A | 1 |  |  |  | P | 1
B2 | CPL | bit | 2 |  |  |  |  | 1
B3 | CPL | C | 1 | CY |  |  |  | 1
D4 | DA | A | 1 | CY |  |  | P | 1
16 + i | DEC | @Ri | 1 |  |  |  |  | 1
14 | DEC | A | 1 |  |  |  | P | 1
15 | DEC | direct | 2 |  |  |  |  | 1
18 + n | DEC | Rn | 1 |  |  |  |  | 1
84 | DIV | AB | 1 | CY |  | OV | P | 4
D5 | DJNZ | direct, rel | 3 |  |  |  |  | 2
D8 + n | DJNZ | Rn, rel | 2 |  |  |  |  | 2
06 + i | INC | @Ri | 1 |  |  |  |  | 1
04 | INC | A | 1 |  |  |  | P | 1
05 | INC | direct | 2 |  |  |  |  | 1
A3 | INC | DPTR | 1 |  |  |  |  | 2
08 + n | INC | Rn | 1 |  |  |  |  | 1
20 | JB | bit, rel | 3 |  |  |  |  | 2
10 | JBC | bit, rel | 3 |  |  |  |  | 2
40 | JC | rel | 2 |  |  |  |  | 2
73 | JMP | @A+DPTR | 1 |  |  |  |  | 2
30 | JNB | bit, rel | 3 |  |  |  |  | 2
50 | JNC | rel | 2 |  |  |  |  | 2
70 | JNZ | rel | 2 |  |  |  |  | 2
60 | JZ | rel | 2 |  |  |  |  | 2
12 | LCALL | addr16 | 3 |  |  |  |  | 2
02 | LJMP | addr16 | 3 |  |  |  |  | 2
76 + i | MOV | @Ri, #const8 | 2 |  |  |  |  | 1
F6 + i | MOV | @Ri, A | 1 |  |  |  |  | 1
A6 + i | MOV | @Ri, direct | 2 |  |  |  |  | 2
74 | MOV | A, #const8 | 2 |  |  |  | P | 1
E6 + i | MOV | A, @Ri | 1 |  |  |  | P | 1
E5 | MOV | A, direct | 2 |  |  |  | P | 1
E8 + n | MOV | A, Rn | 1 |  |  |  | P | 1
92 | MOV | bit, C | 2 |  |  |  |  | 2
A2 | MOV | C, bit | 2 | CY |  |  |  | 1
75 | MOV | direct, #const8 | 3 |  |  |  |  | 2
86 + i | MOV | direct, @Ri | 2 |  |  |  |  | 2
F5 | MOV | direct, A | 2 |  |  |  |  | 1
85 | MOV | direct, direct | 3 |  |  |  |  | 2
88 + n | MOV | direct, Rn | 2 |  |  |  |  | 2
90 | MOV | DPTR, #const16 | 3 |  |  |  |  | 2
78 + n | MOV | Rn, #const8 | 2 |  |  |  |  | 1
F8 + n | MOV | Rn, A | 1 |  |  |  |  | 1
A8 + n | MOV | Rn, direct | 2 |  |  |  |  | 2
93 | MOVC | A, @A+DPTR | 1 |  |  |  | P | 2
83 | MOVC | A, @A+PC | 1 |  |  |  | P | 2
F0 | MOVX | @DPTR, A | 1 |  |  |  |  | 2
F2 + i | MOVX | @Ri, A | 1 |  |  |  |  | 2
E0 | MOVX | A, @DPTR | 1 |  |  |  | P | 2
E2 + i | MOVX | A, @Ri | 1 |  |  |  | P | 2
A4 | MUL | AB | 1 | CY |  | OV | P | 4
00 | NOP |  | 1 |  |  |  |  | 1
44 | ORL | A, #const8 | 2 |  |  |  | P | 1
46 + i | ORL | A, @Ri | 1 |  |  |  | P | 1
45 | ORL | A, direct | 2 |  |  |  | P | 1
48 + n | ORL | A, Rn | 1 |  |  |  | P | 1
A0 | ORL | C, /bit | 2 | CY |  |  |  | 2
72 | ORL | C, bit | 2 | CY |  |  |  | 2
43 | ORL | direct, #const8 | 3 |  |  |  |  | 2
42 | ORL | direct, A | 2 |  |  |  |  | 1
D0 | POP | direct | 2 |  |  |  |  | 2
C0 | PUSH | direct | 2 |  |  |  |  | 2
22 | RET |  | 1 |  |  |  |  | 2
32 | RETI |  | 1 |  |  |  |  | 2
23 | RL | A | 1 |  |  |  |  | 1
33 | RLC | A | 1 | CY |  |  | P | 1
03 | RR | A | 1 |  |  |  |  | 1
13 | RRC | A | 1 | CY |  |  | P | 1
D2 | SETB | bit | 2 |  |  |  |  | 1
D3 | SETB | C | 1 | CY |  |  |  | 1
80 | SJMP | rel | 2 |  |  |  |  | 2
94 | SUBB | A, #const8 | 2 | CY | AC | OV | P | 1
96 + i | SUBB | A, @Ri | 1 | CY | AC | OV | P | 1
95 | SUBB | A, direct | 2 | CY | AC | OV | P | 1
98 + n | SUBB | A, Rn | 1 | CY | AC | OV | P | 1
C4 | SWAP | A | 1 |  |  |  |  | 1
C6 + i | XCH | A, @Ri | 1 |  |  |  | P | 1
C5 | XCH | A, direct | 2 |  |  |  | P | 1
C8 + n | XCH | A, Rn | 1 |  |  |  | P | 1
D6 + i | XCHD | A, @Ri | 1 |  |  |  | P | 1
64 | XRL | A, #const8 | 2 |  |  |  | P | 1
66 + i | XRL | A, @Ri | 1 |  |  |  | P | 1
65 | XRL | A, direct | 2 |  |  |  | P | 1
68 + n | XRL | A, Rn | 1 |  |  |  | P | 1
63 | XRL | direct, #const8 | 3 |  |  |  |  | 2
62 | XRL | direct, A | 2 |  |  |  |  | 1


BOOT-51 User's Manual

MCS-51 Microcontroller Family Bootstrap Program

USER'S MANUAL

Version 1.1

December 15, 2002

Copyright © 1996, 2002 by W.W. Heinz

TABLE OF CONTENTS

  1. Introduction
  2. BOOT-51 Installation
    1. Files
    2. Customizing BOOT-51
    3. Tailoring the Cables
    4. Design of MCS-51 Evaluation Boards
  3. BOOT-51 Operation
    1. Interactive Operation
    2. Batch File Operation under MS-DOS
    3. DOS Upload Utilities
    4. Shell Script Operation under Linux
    5. The BLINK Program
  4. Troubleshooting
    1. General Trouble
    2. Trouble under MS-DOS
    3. Trouble under Linux

APPENDIX

  1. CUSTOMIZ Error Messages
    1. Parameter Errors
    2. Baudrate Errors
    3. Runtime Errors
  2. RESET51 Error Messages
  3. BOOT-51 Error Messages
  4. Trademarks
  5. Tables of Baudrates

Copyright © 1996, 2002 by W.W. Heinz

Last revised: December 15, 2002


BOOT-51 Introduction

I. Introduction

Usually an 8051 application program is not running correctly from scratch, and it is not quite easy to debug it without a suitable test equipment. It is very inconvenient, to burn the program into an EPROM after every change. Instead it would be nice to load the program into the external RAM of the target board and then start it. This would dramatically speed up the turn-around cycles. However, three problems must be solved first:
  1. There must be a suitable interface to transmit the application program from the host (PC) to the target (8051) system.
  2. The target board needs a suitable firmware that can receive a program from the host computer, store it in the external RAM, and finally execute it.
  3. Once loaded, the application program must be executable, although it is stored in the external RAM, which is usually mapped into the XDATA address space.
    (Programs can only be executed in the CODE address space!)
The corresponding three solutions are:
  1. an RS-232 interface between the PC and the 8051 board
  2. a bootstrap program
  3. external RAM that is mapped into both the CODE and XDATA address space

Nearly all evaluation boards for 8051 derivatives are meeting requirements 1 and 3. In most cases, it is easy to establish a memory map according to requirement 3, even on target boards that do not originally support it.
(See chapter II.4 Design of MCS-51 Evaluation Boards.)

Requirement 2 can be met by burning a customized version of BOOT-51 into the EPROM of the target board. After system reset, it can receive an Intel-HEX file over the serial interface, store it in the external RAM, and finally jump to the program start address.

BOOT-51 itself doesn't need any external RAM, and requires only 1 kB of EPROM. In principle, it is not restricted to a PC-based host system, but presently only the host platforms MS-DOS, Windows 9x, and Linux (i386) are supported.

Sure, a bootstrap program cannot replace a target debugger, but it's a start.


BOOT-51 Installation

II. BOOT-51 Installation

The BOOT-51 support files are usually installed on the host system together with the latest ASEM-51 version. Of course BOOT-51 must be installed on the MCS-51 target system, too.
Before burning BOOT-51 into an EPROM, it must be customized for the target board, and one or two cables must be tailored for local requirements.
If the design of the target system is not yet finished, some basic knowledge, concerning the general design of MCS-51 evaluation boards, might be helpful to meet the hardware requirements from the beginning.
  1. Files
  2. Customizing BOOT-51
  3. Tailoring the Cables
  4. Design of MCS-51 Evaluation Boards


BOOT-51 Files

II.1 Files

The BOOT-51 package for DOS/Windows consists of the following files:

BOOT51.DOC | BOOT-51 User's Manual, ASCII format
BOOT51.HTM | index file of the BOOT-51 documentation, HTML format
*.HTM | further pages of the HTML documentation
*.GIF | GIF images referenced by HTML pages
BOOT51.A51 | BOOT-51 assembler source (for ASEM-51 V1.3 and up)
CUSTOMIZ.EXE | BOOT-51 customization utility
BOOT.BAT | batch file for application program upload
UPLOAD.BAT | called by BOOT.BAT only
COMPORT.EXE | setup utility for PC serial ports
RESET51.EXE | program to reset target system via PC ports
SLEEP.EXE | program to wait for the reset recovery time
BLINK.A51 | sample test program for BOOT-51

The BOOT-51 package for Linux consists of the following files:

boot51.doc | BOOT-51 User's Manual, ASCII format
boot51.htm | index file of the BOOT-51 documentation, HTML format
*.htm | further pages of the HTML documentation
*.gif | GIF images referenced by HTML pages
boot51.a51 | BOOT-51 assembler source (for ASEM-51 V1.3 and up)
customiz | BOOT-51 customization utility
customiz.1 | man-page for customiz
boot | shell script for application program upload
boot.1 | man-page for boot
upload | called by boot only (generic version)
upload.new | ”new” upload (optimized for stty 2.0 or later)
reset51 | program to reset target system via PC ports
reset51.1 | man-page for reset51
blink.a51 | sample test program for BOOT-51


Customizing BOOT-51

II.2 Customizing BOOT-51

BOOT-51 must be customized for the target board, before it is ready for assembly. This is performed with an include file boot51.inc, containing the required configuration data. boot51.inc is generated with the BOOT-51 Customization Utility CUSTOMIZ.
There are two major groups of configuration parameters:

  • baudrate generation
  • memory addresses

CUSTOMIZ is invoked as shown below:

   customiz <baud> [<timer> [<prec> [<clock> [<start> [<user>]]]]]

The first four parameters are for baudrate generation, and the last two parameters are memory addresses. Parameters in brackets are optional.
If CUSTOMIZ is invoked without parameters, it displays a help screen.

<baud> | is the desired nominal baudrate (in Baud), BOOT-51 should use for communication with the host system.
<timer> | is the on-chip timer or baudrate generator that is used for baudrate generation. Legal values are: T1 = timer 1, available on nearly all 8051 derivatives (default) T2 = timer 2, available on 8052/32 and all true compatibles BG = internal baudrate generator on 80C515/35 and 80C517/37 BA = internal baudrate generator on 80C515A and 80C517A D1 = timer 1 with clock/12 or clock/4 prescaler on 80C320
<prec> | is the required relative precision of the baudrate in %. The default precision is 1.0 %.
<clock> | is the system clock frequency in MHz. (11.0592 MHz default)
<start> | is the start address of BOOT-51 on the target system in hex representation. (default is 0000H)
<user> | is the usual hex start address of the application programs in the external memory. (default is 8000H)

Baudrate:

For the serial interface, the standard UART is used that is available on almost every 8051 derivative. BOOT-51 is always running the UART in Mode 1, that is asynchronous mode, 8 data bits, 1 stop bit, no parity.
However, depending on the derivative, there may be various timers or prescalers that can be used for baudrate generation.
If the desired baudrate cannot be generated or the precision is too bad, CUSTOMIZ will display a corresponding error message. In this case, try another baudrate generator that is also available on your derivative. If this fails, too, try another baudrate that may also do, or think of using another oscillator crystal that suits better for the task. You should play around with CUSTOMIZ, to explore how to get best results. The tables in Appendix E show the precisions of the most frequently used baudrates that can be generated with the supported timers and baudrate generators, for some standard clock frequencies. In most cases baudrate deviations of 2 to 3 % are no problem for the communication with a PC. Whenever in doubt, try it!
BOOT-51 can receive data at very high baudrates without the need for a handshake protocol. Output is done more slowly with short pauses between the characters, to avoid a data overrun of the PC UART. The maximum effective output speed of BOOT-51 is corresponding to 9600 Baud (max. 1 character per ms).
In general, speed is rather a problem for the PC than for the micro.

Example 1: | customiz 9600 BG 0.1 12
 | will generate an include file for BOOT-51 that configures it for 9600 Baud, generated with the internal baudrate generator of a SAB80C535 or SAB80C537 that is clocked with 12.0 MHz. The required precision is 0.1 %. The bootstrap and application program start addresses are set to their default values.

Addresses:

<start>:
An 8051 starts program execution at CODE address 0000H after reset. Thus there must always be ROM at CODE address 0000H to execute the first instructions. On most 8051 boards there is EPROM in the range 0000H-7FFFH, and RAM in the range 8000H-FFFFH. However, the final application programs will usually start at address 0000H, and the 8051 interrupt addresses start at address 0003H. If application programs can be loaded into RAM at 8000H, this is normally not quite realistic for testing.
Hence it would be nice to have CODE/XDATA-RAM at address 0000H to load and test application programs. That is why some evaluation boards (e.g. the Keil MCB-517) remap the EPROM from address 0000H to 8000H, and the RAM from 8000H to 0000H, when the first memory access to a CODE address > 7FFFH occurs.
To support this, BOOT-51 starts with a long jump to its entry point, to eventually remap the memory. If you own a corresponding evaluation board, specify the <start> address of BOOT-51 to the location, where it resides after memory remapping!

<user>:
In principle, BOOT-51 can load an application program at any location in the external RAM and start it there. However, the interrupt addresses should be redirected to the location, where application programs usually start, e.g. the start address of the external RAM.
Hence the <user> address should point to the location, where the CODE/XDATA-RAM starts. If it starts at 8000H, interrupt 0003H is redirected to 8003H, interrupt 000BH to 800BH, and so on.
If the CODE/XDATA-RAM starts at 0000H (after remapping), the <user> address has no practical meaning and can be left default.

Example 2: | customiz 19200 T2 1 11.0592 0 C000
 | will generate an include file for BOOT-51 that configures it for 19200 Baud, generated with timer 2 of an 80C52 or 80C32 that is clocked with 11.0592 MHz. The required precision is 1 %. BOOT-51 is located at address 0000H in the EPROM, and the interrupt addresses are redirected to location 0C000H.

If CUSTOMIZ aborts with an error message, it returns exit code 1 on parameter- and baudrate-errors, and exit code 2 on fatal runtime errors. When CUSTOMIZ terminates without error message, it returns exit code 0, and a customization header file boot51.inc should be present in the default directory. With this file, BOOT-51 can be assembled as usual with

ASEM BOOT51                           (DOS)
asem boot51.a51                       (Linux)

Remember that BOOT-51 requires ASEM-51 V1.3 or later!
Now there should be an Intel-HEX file boot51.hex, which may serve directly as an input for the EPROM programmer. We may also convert it to a binary image file with the HEXBIN utility:

HEXBIN BOOT51/LENGTH:4000              (DOS)
hexbin -l 4000 boot51.hex              (Linux)

would generate a binary image file boot51.bin for a 16 kB EPROM (27C128).
(Note: Only 1 kB of EPROM is required for the BOOT-51 program code.)
Once in an EPROM, BOOT-51 should be ready to run on the target system.


Tailoring the Cables

II.3 Tailoring the Cables

Application programs are uploaded to the target system over a serial interface. The serial ports of the PC may have 9-pin or 25-pin male D-Shell connectors. Suitable RS-232 cables for the MCS-51 board can be tailored as follows:

RS-232 cable with 25-pin female D-Shell connector
RS-232 cable with 25-pin female D-Shell connector

Shortening the modem control signals is absolutely required for batch operation under MS-DOS! If the CTS-, DSR-, or DCD-input is not set to logic low (+12V), the PC will hang during character output to the serial port.
For shell script operation under Linux, only the Tx-, Rx-, and ground lines are required, and the handshake inputs may be left open. The same is true for interactive operation with most terminal emulation programs. (For further information refer to the documentation of your terminal emulation program.)
If there is a spare RS-232 line receiver on your MCS-51 board, it can be employed as a reset input! In this case, the target system can be reset in batch (or script) files with the reset program provided, and from terminal emulation programs (by dropping the DTR output with the hang-up function).

RS-232 cable with 9-pin female D-Shell connector
RS-232 cable with 9-pin female D-Shell connector

If you own a 9/25-pin mouse adaptor with all pins connected, the 9-pin version of the cable should be preferred!
If your MCS-51 board has no spare RS-232 line receivers, but a TTL reset input (or you can establish one), the target system can also be reset in batch (or script) files over a printer port of the PC. For this, a suitable reset cable must be tailored as shown below:

Reset cable with 25-pin male D-Shell connector
Reset cable with 25-pin male D-Shell connector

In practice, only one of the two reset lines will be required. When the reset program is invoked, a positive reset pulse appears at D0 (8031, 8032), and a negative pulse at D1 (80C535, 80C537). For detailed information on the reset program, refer to chapters III.2 Batch File Operation under MS-DOS, and III.4 Shell Script Operation under Linux.


Design of MCS-51 Evaluation Boards

II.4 Design of MCS-51 Evaluation Boards

When developing embedded systems, debugging aspects should be taken into account as soon as possible. That is why MCS-51 prototype boards should always be armed with a download RAM in the hardware design phase, even if the serial model (probably) doesn't need an external RAM!
A $3 RAM can save a $3000 in-circuit emulator and weeks of trouble!

Before discussing the basic concepts of program download, it is essential to understand the memory organization of the MCS-51 architecture.
First of all, there is an 8-bit address space for internal RAM. Parts of it are directly addressable (DATA space), indirectly addressable (IDATA space), or bit-addressable (BIT space). These address spaces are fully or partly overlapping. Furthermore, the four register banks and the Special Function Registers (SFR) are mapped into this internal address space. This is hard to understand for newbies, but plays no role for program download.
Aside of the internal memory, the MCS-51 architecture provides a bus interface for external memory. There are two separate 16-bit address spaces for 64K of program memory (ROM) and 64K of data memory (RAM). Program memory (CODE space) can only be read with the -PSEN bus signal, and data memory (XDATA space) can be read and written with the -RD and -WR bus signals. The -PSEN signal becomes active during instruction fetch cycles and MOVC instructions. The -RD and -WR signals become active during read and write operations with MOVX instructions.

The obvious problem is: a downloaded program can only be stored in external RAM, mapped into the XDATA space, whereas program code can only be executed from memory in the CODE space.
There must be a way to execute a downloaded program, although it is stored in external RAM! Fortunately, there is a simple trick to solve this:
The -OE input of the (usually static) RAM must be driven by a logic AND of the -RD and -PSEN signals of the MCU, rather than by -RD alone. That's all!
Then the external RAM can be read and written with MOVX instructions (using -RD and -WR), and program code can be executed from it (using -PSEN).

For example, a typical 8051 evaluation board could be designed as follows:
A 32K EPROM (e.g. 27C256) is mapped into the CODE space from address 0000H to 7FFFH, containing BOOT-51 at address 0000H.
A 32K static RAM (e.g. 62256) is mapped into both the CODE and XDATA spaces from address 8000H to FFFFH.
After reset, the MCU starts program execution at address 0000H, and BOOT-51 is running, waiting for commands. When it receives an UPLOAD command from the host computer, it reads an Intel-HEX file and stores it at its start address in the external RAM (e.g. 8000H). If BOOT-51 receives a GO TO 8000 command, it jumps to the specified address 8000H, and the downloaded program is running.
A memory map like this can be obtained with a minimum of hardware:
The -CE (chip enable) input of the EPROM must be driven by the A15 signal (P2.7) of the MCU, and -CE of the RAM with the inverted A15 signal respectively, to avoid bus conflicts in the CODE space.
The -OE (output enable) input of the EPROM must be driven by the -PSEN signal of the MCU, as usual for CODE memory.
The -WE (write enable) input of the RAM must be driven by the -WR signal (P3.6) of the MCU, as usual for XDATA memory.
Only the -OE (output enable) input of the RAM must be driven by that famous logical AND of the -RD and -PSEN signals of the MCU, to map the RAM into both the XDATA and CODE space. That's it!

Because this is so simple, cheap and (in contrast to many in-circuit emulators) absolutely reliable, most MCS-51 family evaluation boards are working like this or similar.
In most cases, it is easy to establish a suitable memory map, even on target boards that do not originally support it.

If there is no spare AND gate, it may also do, to simply connect the -OE input of the RAM to the -PSEN signal of the MCU only. In this case, the RAM can still be written, but no longer be read with MOVX instructions. Since program code can also be executed from it, this minimized version can still be used as download RAM, but no longer as external data RAM.
(In cases of emergency, it can be read with MOVC instructions, however!)


BOOT-51 Operation

III. BOOT-51 Operation

When BOOT-51 is customized correctly, and the target board is connected to the host PC with the cable(s) described above, we can start to upload and run application programs. There are two possible modes of operation:
  • interactive operation
  • batch operation
  1. Interactive Operation
  2. Batch File Operation under MS-DOS
  3. DOS Upload Utilities
  4. Shell Script Operation under Linux
  5. The BLINK Program


Interactive Operation

III.1 Interactive Operation

BOOT-51 implements a simple ASCII user interface for serial communication. The bootstrap program can be operated interactively with a terminal emulation program running on the PC (e.g. TELIX under MS-DOS, or minicom under Linux). To perform this, start your terminal emulation program, and configure it for the correct baudrate, 8 data bits, 1 stop bit, no parity, and no handshake. Then reset the MCS-51 target system.
(If you have established an RS-232 reset line, the target system can usually be reset by dropping the RS-232 DTR output with the ”hang-up” function!) Now the BOOT-51 sign-on message should appear on your screen:

BOOT-51  V1.1             Copyright (c) 2002 by W.W. Heinz

>

The '>' character indicates that the BOOT-51 command line interpreter is ready for input. It implements exactly two commands:

  1. The UPLOAD command:
    First press the 'U', and then the return key.
    Now the upload prompt ':' should be displayed. BOOT-51 is now ready to receive an application program in Intel-HEX format. Send an Intel-HEX file with the ASCII upload function of your terminal emulation program. (Be sure that it terminates every line with a CR and/or LF character!) Now the received Intel-HEX records are loaded to their start addresses specified in the record headers. If an EOF record is received, the upload is terminated and the command prompt '>' is displayed again. Now the command line interpreter is ready for the next command.
    When a format error is detected in the Intel-HEX file, BOOT-51 waits until no more characters are received for about two seconds, and then aborts with a corresponding error message. (see Appendix C)
  2. The GO TO command:
    To start an application program at address 8000H, enter ”G 8000” and press return. BOOT-51 sets now all MCU registers to reset conditions (as far as possible), and jumps to the start address specified. Now the previously loaded application program should be running!

Any desired number of Intel-HEX files may be loaded, before entering the 'G' command. The commands may be entered in upper or lower case letters. Interactive operation should be preferred, if the application program performs serial I/O. This can easily be supervised with the terminal emulation program. In interactive mode, only an RS-232 reset output is applicable. (A printer port reset cable would be of little use!)


Batch File Operation under MS-DOS

III.2 Batch File Operation under MS-DOS

If serial I/O is only used for program upload, batch file operation may be the most convenient way of testing with the shortest turn-around cycles. The sample batch job below, shows the principles of operating BOOT-51 from a PC with MS-DOS batch commands:

MODE COM2:9600,N,8,1,P
RESET51 LPT1
SLEEP 9600
ASEM %1
ECHO U >COM2
COPY %1.HEX COM2
ECHO G 8000 >COM2

In this example, serial I/O is done over serial port COM2, and the target system can be reset over printer port LPT1.
First of all, the serial port COM2 is initialized to the desired baudrate of 9600 Baud, 8 data bits, 1 stop bit, and no parity with the MODE utility. Then the RESET51 program provided is executed to reset the target system via printer port LPT1. After that, the SLEEP program waits until BOOT-51 has fully output its sign-on message at 9600 Baud and is ready for a command. To give the MCS-51 board some more time to recover from reset, ASEM-51 is now invoked to assemble the application program.
When finished, the BOOT-51 upload command 'U' is ECHOed to COM2, and the Intel-HEX file is also simply copied to the serial port.
Finally the application program is started at address 8000H with the command ”ECHO G 8000 >COM2”.
To test an application program MYPROG.A51 with the above batch job (stored in a file TEST51.BAT), simply type

TEST51 MYPROG

at the DOS prompt, and see what you get.
Of course this was only a minimized example! In general you will not only have to modify serial port, baudrate, reset port, and start address for your local requirements, but also to do something for plausibility checking and error handling.
For this, the more sophisticated batch file BOOT.BAT has been provided. It allows an easy change of all configuration parameters with any ASCII editor. For further information see the commentary inside BOOT.BAT. In principle, BOOT.BAT contains only those configuration data! (The actual work is done by another batch file UPLOAD.BAT provided, which is invoked by BOOT.BAT.)
A program MYPROG.A51 can now be assembled, uploaded and started with

BOOT MYPROG


DOS Upload Utilities

III.3 DOS Upload Utilities

The BOOT-51 package for DOS/Windows contains the utilities COMPORT.EXE, RESET51.EXE, and SLEEP.EXE, which are usually invoked by UPLOAD.BAT, but can also be used separately.

COMPORT

sets <baudrate> and data format of a PC serial <port>:

COMPORT <port> <baudrate> [<parity> [<databits> [<stopbits>]]]

Legal parameter values are:

<port>: AUX, COM1, COM2, COM3, COM4
<baudrate>: 1.66 < baudrate < 121000
<parity>: N, O, E, M, S (default: N)
<databits>: 5, 6, 7, 8 (default: 8)
<stopbits>: 1, 1.5, 2 (default: 1)

The port names AUX and COM1 are equivalent.
COMPORT allows to set very low, very high, and very odd baudrates, which can be generated by the 16C450 UART of the PC (and the 8051 board), but are not supported by the PC BIOS or the MS-DOS MODE command.
Baudrates that cannot be generated exactly are accepted as long as the deviation doesn't exceed 5.0 %. COMPORT displays the ”real” baudrate and the relative deviation (if any) from the nominal value.
The parity can optionally be set to N (none), O (odd), E (even), M (mark), or S (space). Furthermore, the data format can be set to 5, 6, 7, or 8 data bits, and 1, 1.5, or 2 stop bits.
Default settings are: no parity, 8 data bits and 1 stop bit.

Note: only 6, 7 or 8 data bits may be combined with 1 or 2 stop bits.
5 data bits are only possible with 1.5 stop bits!

Example 1: | COMPORT COM4 12800
 | Sets the serial port COM4 to 12800 Baud, no parity, 8 data bits, and 1 stop bit.

RESET51

forms a reset pulse of the duration <pulsewidth> at the D0 and D1 outputs of a PC printer <port>, or at the DTR output of a serial <port>:

RESET51 <port> [<pulsewidth>]

Legal <port> values are: PRN, LPT1, LPT2, LPT3,
AUX, COM1, COM2, COM3, COM4,
NUL

PRN and LPT1 are equivalent, and so are AUX and COM1.
The optional parameter <pulsewidth> is the duration of the reset pulse in ms.
Legal values are: 1 <= <pulsewidth> <= 65535. (default is 50)
When invoked without parameters, a help screen is displayed.
In case of error, RESET51 returns the ERRORLEVEL 1, 0 otherwise.
When executed, RESET51 forms a positive pulse at D0 (pin 2), and a negative pulse at D1 (pin 3) of a PC printer port, or a ”high” pulse (-12 V !!!) at the DTR output of a serial port respectively.
If the NUL device is specified as <port>, RESET51 delays only for <pulsewidth> ms.
If the default pulse width of 50 ms is too short to reset the MCS-51 board, specify a greater pulse width.

Example 2: | RESET51 LPT2 500
 | Applies a reset signal to the D0 and D1 outputs of the printer port LPT2 for 500 ms.

RESET51 is running under MS-DOS, and in the DOS-Boxes of Windows 3.1x and 9x.
Windows ME does no longer provide a DOS-Box.
RESET51 is not running under Windows NT, 2000, and XP!

For batch file operation, a reset line is highly recommended! If you don't have it, you will always have to press the reset button of the target system, before invoking BOOT.BAT. Since this may easily be forgotten, it is better to automate this step.

SLEEP

waits until BOOT-51 has output <chars> characters of its sign-on message at a given <baudrate>:

SLEEP <baudrate> [<chars>]

SLEEP is a simple delay program, which is waiting as long as it takes to output <chars> characters with the specified <baudrate>. However, SLEEP takes into account, that BOOT-51 will never send more than one character per ms, even at very high baudrates.
The default value of <chars> is 70, which is slightly more than the total length of the BOOT-51 sign-on message.

Example 3: | SLEEP 300
 | Waits until BOOT-51 has fully output its sign-on message at 300 Baud.


Shell Script Operation under Linux

III.4 Shell Script Operation under Linux

If serial I/O is only used for program upload, shell script operation may be the most convenient way of testing with the shortest turn-around cycles. The sample script file below, shows the principles of operating BOOT-51 from a PC, running under Linux, with shell commands:

  #!/bin/sh
  stty 9600 sane clocal -crtscts -hupcl </dev/ttyS1     # until stty 1.16
  # stty -F /dev/ttyS1 9600 sane clocal -crtscts -hupcl # stty 2.0 or later
  reset51 /dev/lp0
  sleep 1
  asem $1.a51
  echo “U” >/dev/ttyS1
  cp $1.hex /dev/ttyS1
  echo “G 8000” >/dev/ttyS1

In this example, serial I/O is done over serial port /dev/ttyS1, and the target system can be reset over printer port /dev/lp0.
First of all, the serial port /dev/ttyS1 is initialized to the desired baudrate of 9600 Baud, 8 data bits, 1 stop bit, no parity and no handshake with the stty command. (If your stty is version 2.0 or later, better use the new command syntax with the -F option, as shown in commentary!)
Then the reset51 program provided is executed to reset the target system via printer port /dev/lp0. After that, the sleep command waits until BOOT-51 has recovered from reset, fully output its sign-on message, and is ready for a command.
Now ASEM-51 is invoked to assemble the application program.
When finished, the BOOT-51 upload command 'U' is echoed to /dev/ttyS1, and the Intel-HEX file is also simply copied to that serial port.
Finally the application program is started at address 8000H with the command 'echo “G 8000” >/dev/ttyS1'.
To test an application program myprog.a51 with the above shell script (stored in a file test51), simply type

test51 myprog

at the shell prompt, and see what you get.
Of course this was only a minimized example! In general you will not only have to modify serial port, baudrate, reset port, and start address for your local requirements, but also to do something for plausibility checking and error handling.
For this, the more sophisticated script file boot has been provided. It allows an easy change of all configuration parameters with any ASCII editor. For further information see the commentary inside boot.
In principle, boot contains only those configuration data! (The actual work is done by another script upload provided, which is invoked by boot. If your stty command is version 2.0 or later, better use the script file upload.new instead!)
A program myprog.a51 can now be assembled, uploaded and started with

boot myprog

To get the boot script running, ensure that you have full read/write access to the serial port used as upload device!
If a printer port is employed as reset device, the reset51 program requires root privileges! (see below)

Finally, the reset51 program provided, may be worth a detailed explanation: When invoked, reset51 forms a reset pulse of the duration <pulsewidth> at the D0 and D1 outputs of a PC printer <port>, or at the DTR output of a serial <port>:

reset51 /dev/<port> [<pulsewidth>] <

Legal <port> values are: lp0, lp1, lp2,
ttyS0, ttyS1, ttyS2, ttyS3,
cua0, cua1, cua2, cua3,
null

Under Linux with kernels 2.0.x the printer ports are assigned to fixed I/O base addresses (lp0 = 3BCH, lp1 = 378H, lp2 = 278H).
From kernel 2.2.0, the parport layer has been introduced, providing dynamic printer port assignment. If your 2.2.x kernel doesn't contain parport layer support or the /proc file system, you should recompile it respectively. This should also make PCI bus printer ports available as reset devices.
reset51 can only handle the four standard PC serial ports ttyS0 thru ttyS3. (However, the boot script described above should also work with non-standard serial ports, because it operates them with the stty command only!)
The serial ports ttyS0 and cua0 are equivalent, and so are ttyS1 and cua1, and so on.
If /dev/null is specified as <port>, reset51 delays only for <pulsewidth> ms.

The optional parameter <pulsewidth> is the duration of the reset pulse in ms.
Legal values are: 1 <= <pulsewidth> <= 65535. (default is 50)
When invoked without parameters, a help screen is displayed.
In case of error, reset51 returns the exit code 1, 0 otherwise.
When executed, reset51 forms a positive pulse at D0 (pin 2), and a negative pulse at D1 (pin 3) of a PC printer port, or a ”high” pulse (-12 V !!!) at the DTR output of a serial port respectively.
If the default pulse width of 50 ms is too short to reset the MCS-51 board, specify a greater pulse width.

Since reset51 needs direct access to I/O ports, it requires root privileges! To make it available for all users, set the owner to “root” and set the ”set-user-id”-bit:

chown root reset51
chmod u+s reset51

For shell script operation, a reset line is highly recommended! If you don't have it, you will always have to press the reset button of the target system, before invoking the boot script. Since this may easily be forgotten, it is better to automate this step.


The BLINK Program

III.5 The BLINK Program

When BOOT-51 is customized and blown into an EPROM, and the target board is connected to the host PC, it would be nice to verify, whether the whole configuration is working together correctly. This can be done with a short test program that performs a well-defined action when started. For this purpose the tiny assembly program blink.a51 has been provided. It simply toggles the logic level of a port pin (roughly) once a second (great if connected to a LED) to verify, whether all the components in the chain

assembly --» serial interface --» target system «--» bootstrap program

are working together correctly.
It can be adapted to your requirements with little efforts:

  1. If your target system carries a LED that can be switched with a bit-addressable port pin, please change the BIT symbol LEDPIN accordingly. Then the program will make the LED blink.

    If your LED can only be switched with a non-bit-addressable port pin (say bit 2 of a port P6), simply replace the statement CPL LEDPIN  by XRL P6,#00000100B  or something like that.
  2. Change the program start address START to the location, where user programs are usually loaded on your target system.
    The program code itself is position-independent!

If there is no LED on your target system, connect the port pin to a volt-meter. This may also do. Aside of P0 and P2 you may use every port with LEDs or spare outputs. Now the command

boot blink

should reset the MCS-51 board, assemble the test program, upload it to the target system, and finally start it.
red LED If the LED is blinking, everything is now perfectly installed and ready for daily work. If not, you should read the next chapter!


Troubleshooting

IV. Troubleshooting

Of course, you have read all the previous chapters carefully (haven't you?), and you have checked (and double-checked) your hardware, but the damn thing is not willing to work!
If you don't have an idea what may still be wrong, here are some typical cases from my own experience:
  1. General Trouble
  2. Trouble under MS-DOS
  3. Trouble under Linux


General Trouble

IV.1 General Trouble

These are problems that may occur on all host platforms:
  1. The RESET51 program terminates without any error, but the target system is not reset.
    The (reset) cable may be plugged into the wrong (printer) port.
    First of all try the other ports.
    There may also be something wrong with the cable itself.
    Employ the BOOT-51 User's Manual and the circuit diagram of the target board, and check the cable.
    Furthermore, the reset pulse may be too short.
    Specify a greater pulse width.
    You may also decrease the reset capacitor of the MCS-51 system.
  2. The target system is reset all the time.
    When tailoring the reset cable, you may have mixed up the RESET and -RESET lines. Simply interchange them.
  3. In batch (or script) mode everything seems to work fine on the PC, but on the target system you get absolutely nothing.
    Try the interactive mode and reset the target system. If nothing happens, you may have mixed up the receive and transmit lines of the target board. If you get some garbage, the baudrates and/or serial data formats of the target system and the PC are probably different.
    Configure your terminal emulation program correctly, and change BOOT.BAT (under MS-DOS) or the boot script (under Linux) accordingly.
    (correct data format: 8 data bits, 1 stop bit, no parity)
  4. Everything is working fine in batch (or script) mode, but when you try to upload the same HEX file in interactive mode, BOOT-51 aborts with the error message “unexpected character”.
    Check the ASCII upload configuration parameters of your terminal emulation program. It has to terminate every line with a CR and/or LF character, and it must not send any pace characters!
    Of course it is always best, to send the HEX file exactly as it is.


Trouble under MS-DOS

IV.2 Trouble under MS-DOS

These are problems that are specific to DOS-based host platforms, including Windows 3.1x. Most of it also applies to Windows 9x systems.
  1. When initializing the serial port, the DOS MODE utility aborts with an error message like: “function not supported on this computer”, or “invalid parameter”, or something like that.
    On most PCs, the BIOS doesn't support baudrates greater than 9600 Baud. MODE itself doesn't support baudrates greater than 19200 Baud. However, most terminal emulation programs can operate at baudrates of up to 115200 Baud.
  2. The RESET51 program aborts with “port not found”.
    The PC-BIOS didn't recognize the printer or serial port specified.
    Try another port or check your PC hardware.
  3. The RESET51 program aborts with “hardware failure”.
    The PC-BIOS has recognized the specified port, but the data latch (printer port) or modem control register (serial port) doesn't work.
    Try another port, or check the defective port.
  4. The PC hangs when data are sent over the serial interface in batch mode.
    The RS-232 cable may be plugged into the wrong COM-port.
    First of all, try the other ports.
    There may also something be wrong with the modem control signals.
    (See chapter II.3 Tailoring the Cables.)
  5. It works in interactive mode, but the PC hangs, if data are sent in batch mode.
    There is something wrong with the modem control lines!
    Employ the BOOT-51 User's Manual and check the RS-232 cable at the PC side connector.
  6. When invoked, the MS-DOS MODE command hangs, or fails to change the previous baudrate, although it terminates without error.
    Remove all networking and communication drivers and TSR programs from your CONFIG.SYS and AUTOEXEC.BAT files, reboot, and try it again. There is plenty of quick'n dirty software, doing something strange with the BIOS interrupts!


Trouble under Linux

IV.3 Trouble under Linux

The most popular problems under Linux are permission conflicts and wrong (or no) configuration. Problems may even change with the version number of the Linux kernel!
Note that some changes suggested here will lower your systems security against attackers who have login access to your machine. Direct access to hardware ports and security do not mix well.
On some distributions changes in the /dev directory might be detected by periodically run jobs and automatically reverted to the old state.

  1. The boot script aborts with the error message

    ./upload: /dev/ttyS1: Permission denied

    (or something like that).
    You don't have read/write access to the serial port in use (ttyS1).
    If you are the only user of this computer, you can log in as root, and simply allow read/write operations for all users:

        chmod a+rw /dev/ttyS1

    If there are more users who have access to the system, better define a new group called “embedded” (or something) in /etc/group and add all users who need access to this port. Finally do

        chgrp embedded /dev/ttyS1
        chmod o-rw,ug+rw /dev/ttyS1
  2. The boot script hangs on any attempt to output an Intel-HEX file to a particular serial port.
    There may be an I/O address or interrupt conflict, or the serial ports are not configured correctly, or not at all.
    Make sure that every serial port uses a base I/O address and an IRQ that does not conflict with any other hardware installed in your system. (For example, port ttyS3 at 0x2e8 conflicts with an 8514 graphics card!) Check the BIOS setup menu for on-board peripherals, as well as the jumper settings of all the legacy (ISA) boards.
    Watch the console output when Linux is booting. There are messages like

    ttyS00 at 0x03f8 (irq = 4) is a 16550A

    A log file is usually kept in /var/log. The file name depends on the Linux distribution and version. Look for boot.msg, bootlog, or something.
    Linux doesn't really auto-probe the serial ports. It assumes standard port addresses and IRQ numbers. If your hardware doesn't match this default configuration, it will not work. In this case you have to configure your serial ports manually with the setserial command, e.g.

        setserial -v /dev/ttyS0 port 0x3f8 irq 4 autoconfig
        setserial -v /dev/ttyS1 port 0x2f8 irq 3 autoconfig
        setserial -v /dev/ttyS2 port 0x3e8 irq 9 autoconfig
        setserial -v /dev/ttyS3 port 0x2e8 irq 10 autoconfig

    Unfortunately the best place where to put these commands, in order to execute them during system boot, depends on the Linux distribution. For most Linux distributions, /etc/init.d/serial is a good choice! SuSE distributions kept it in /sbin/init.d/serial until version 7.0.
    For detailed information on serial port configuration refer to the setserial man-pages and the Serial-HOWTO.
  3. The boot script aborts with an error message like

         resetting target system ...
    @@@@@ access denied: /dev/lp0 @@@@@

    on a system with a 2.2.x (or later) kernel, or with

         resetting target system ...
    @@@@@ no root privilege @@@@@

    on a system with a 2.0.x (or earlier) kernel.
    The reset51 program needs root privileges for direct access to I/O ports!
    If you are the only user of this computer, you can log in as root, and simply allow to run reset51 as root for all users:

        chown root reset51
        chmod a+x,u+s reset51

    Once again a warning: don't do this, if your system should have a higher level of security! If there are more users who have access to the system, better define a special group “embedded” (or something) in /etc/group and add all users who need to run reset51. Then disable execution for all other users:

        chown root reset51
        chgrp embedded reset51
        chmod o-x,ug+x,u+s reset51

    This may considerably improve your system security.
  4. The boot script aborts with the error message

         resetting target system ...
    @@@@@ hardware failure: lp0 @@@@@

    although there are two perfectly working printer ports in your PC.
    The reason may be that you run a 2.0.x (or earlier) Linux kernel, which assigns fixed I/O base addresses to the printer port devices: there is no printer port with base address 0x3bc in your system!
    Try /dev/lp1 (0x378) and /dev/lp2 (0x278) as reset devices, and change your boot script accordingly.
  5. The boot script aborts with the error message

         resetting target system ...
    @@@@@ port not found: /dev/lp2 @@@@@

    on a PC with two printer ports and a 2.2.x (or later) kernel.
    There is no entry for /dev/lp2 in /proc/parport/2!

    From version 2.2.0 the Linux kernel provides the parport layer for dynamic printer port assignment, as known from the PC-BIOS. If you have recently updated from a 2.0.x (or earlier) kernel, your previous printer port /dev/lp2 may now simply be called /dev/lp1 in a 2.2.x (or later) system.
    Try /dev/lp1 as reset device, and change your boot script accordingly.
    If this doesn't apply, make sure that
    • the /proc file system is configured and mounted
    • the kernel contains the kernel module loader kmod
    • the kernel is configured for parport support
    • the kernel modules lp, parport, and parport_pc are loaded
    • all printer ports are configured in /etc/modules.conf, e.g.

      options parport_pc io=0x378,0x278 irq=7,none

    Configure and recompile your kernel respectively, if necessary. For further information refer to the documentation files parport.txt, modules.txt, kmod.txt and README provided with recent kernel sources, or ask a real Linux expert!
    (See also chapter III.4 Shell Script Operation under Linux.)
  6. The boot script aborts with the error message

         resetting target system ...
    ./upload: /dev/ttyS4: Device or resource busy

    The interrupt of the serial interface may already be used by another driver (i.e. printer port, USB).
    Try to find and solve the interrupt conflict. (See items 2 and 5.)


BOOT-51 Appendix A

Appendix A

CUSTOMIZ Error Messages

A.1 Parameter Errors:

Parameter errors apply to the correctness and consistency of the command line parameters. If one of these errors is detected, it is flagged on the console, and CUSTOMIZ is aborting with exit code 1:

Error Message | Meaning
accuracy out of range | Baudrate accuracy < 0, or > 5 %.
address out of range | Address is no unsigned 16-bit number.
baudrate out of range | Specified baudrate is < 0.
clock frequency out of range | Specified clock frequency is < 0.
illegal real number | Parameter is no valid real number.
invalid hex number | Parameter is no valid hex number.
too many parameters | More than 6 parameters specified.
unknown baudrate generator | Baudrate generator not implemented.

A.2 Baudrate Errors:

Baudrate errors apply to the results that CUSTOMIZ has derived from the given program parameters. If one of these errors is detected, it is flagged on the console, and CUSTOMIZ is aborting with exit code 1:

Error Message | Meaning
baudrate cannot be generated | Baudrate error is greater than 10 %.
insufficient accuracy | Baudrate error is greater than the required accuracy.

A.3 Runtime Errors:

In general, runtime errors are file I/O errors.
If one of these errors is detected, it is flagged on the console, and CUSTOMIZ is aborting with exit code 2:

Error Message | Meaning
access denied | No privilege for attempted operation.
disk full | No more free disk space.
disk write-protected | Attempt to write to a write-protected disk.
drive not ready | Disk drive is off, or no media mounted.
fatal I/O error | General (unknown) disk or device I/O error.


BOOT-51 Appendix B

Appendix B

RESET51 Error Messages

General Errors:
Error Message | Meaning
too many parameters | More than two parameters specified.
illegal port name | Unknown device name.
invalid pulse-width | Pulse width is 0, or no unsigned 16-bit number.
hardware failure | The port register cannot be read back.

MS-DOS only:
Error Message | Meaning
port not found | The BIOS did not recognize the port.

Linux only:
Error Message | Meaning
no root privilege | Program doesn't run as root.
access denied | No r/w access to character device.
port not found | Port entry not found in /proc/parport
invalid base address | Format error in /proc/parport/n/hardware


BOOT-51 Appendix C

Appendix C

BOOT-51 Error Messages

Error Message | Meaning
checksum error | Intel-HEX record checksum is not correct.
illegal command | A command other than U or G has been entered.
illegal hex digit | Hex digit expected. Another character received.
illegal record ID | Intel-HEX record type is greater than 1.
unexpected character | The received Intel-HEX record doesn't start with ':', or doesn't end with CR, LF, or CR/LF.


BOOT-51 Appendix D

Appendix D

Trademarks

ASEM-51 is a trademark of W.W. Heinz.
MCS-51 is a trademark of Intel Corporation.
MCB-517 is a trademark of Keil Elektronik GmbH.
TELIX is a trademark of deltaComm Development.
IBM-PC, IBM-XT, and IBM-AT are trademarks of IBM Corporation.
MS-DOS is a trademark of Microsoft Corporation.
Windows is a trademark of Microsoft Corporation.
Linux is a trademark of Linus Torvalds.
All device codes of 8051 derivatives are trademarks of the manufacturers.
Other brand and product names are trademarks of their respective holders.


BOOT-51 Appendix E

Appendix E

Tables of Baudrates

The following tables show the most frequently used baudrates that can be generated with a particular timer or baudrate generator, for some standard clock frequencies.
Baudrates which can be generated with a relative accuracy of better than 4.0 %, are marked with that accuracy (in %) or with a '+' character, if they can be generated exactly (better than 0.01 %).

Baudrates that can be generated with Timer 1:
MHz bps | 7.3728 | 11.0592 | 12.0000 | 14.7456 | 16.0000 | 18.0000 | 20.0000 | 24.0000
128000 |  |  |  |  |  |  |  | 2.34
76800 |  |  |  | + |  |  |  |
64000 |  |  | 2.34 |  |  |  |  | 2.34
57600 |  | + |  |  |  |  |  |
38400 | + |  |  | + |  |  |  |
31250 |  |  | + |  |  | + |  | +
19200 | + | + |  | + |  | 2.34 |  |
14400 |  | + |  |  | 3.55 |  | 3.34 | 3.55
12500 | 2.40 |  | + | 2.40 |  |  |  | +
9600 | + | + |  | + | 3.55 | 2.34 | 1.36 | 0.16
7200 |  | + | 3.55 | 3.03 | 3.55 | 0.16 | 3.34 | 2.12
4800 | + | + | 0.16 | + | 2.12 | 2.34 | 1.36 | 0.16
3600 | 3.03 | + | 2.12 | 1.59 | 0.64 | 0.16 | 0.22 | 0.79
2400 | + | + | 0.16 | + | 0.79 | 0.16 | 0.94 | 0.16
1800 | 1.59 | + | 0.79 | 0.78 | 0.64 | 0.16 | 0.22 | 0.64
1200 | + | + | 0.16 | + | 0.64 | 0.16 | 0.22 | 0.16
600 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
300 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
200 | + | + | 0.16 | + | 0.16 | 0.16 | 1.73 |
150 | + | + | 0.16 | + |  |  |  |
134 | 0.20 | 0.03 | 0.09 |  |  |  |  |
110 | 0.26 | 2.27 |  |  |  |  |  |
75 | + |  |  |  |  |  |  |

Baudrates that can be generated with Timer 2 of the 8052:
MHz bps | 7.3728 | 11.0592 | 12.0000 | 14.7456 | 16.0000 | 18.0000 | 20.0000 | 24.0000
460800 |  |  |  | + |  |  |  |
256000 |  |  |  |  | 2.34 |  |  | 2.34
230400 | + |  |  | + |  |  |  |
128000 |  |  | 2.34 |  | 2.34 |  | 2.34 | 2.34
115200 | + | + |  | + |  | 2.34 |  |
76800 | + |  | 2.34 | + |  |  | 1.73 | 2.34
64000 |  |  | 2.34 | 2.86 | 2.34 | 2.34 | 2.34 | 2.34
57600 | + | + |  | + | 3.55 | 2.34 | 1.36 | 0.16
38400 | + | + | 2.34 | + | 0.16 | 2.34 | 1.73 | 2.34
31250 |  | 0.54 | + | 1.70 | + | + | + | +
19200 | + | + | 2.34 | + | 0.16 | 1.02 | 1.36 | 0.16
14400 | + | + | 0.16 | + | 0.79 | 0.16 | 0.94 | 0.16
12500 | 2.40 | 1.26 | + | 0.37 | + | + | + | +
9600 | + | + | 0.16 | + | 0.16 | 0.69 | 0.16 | 0.16
7200 | + | + | 0.16 | + | 0.64 | 0.16 | 0.22 | 0.16
4800 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
3600 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
2400 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
1800 | + | + | 0.16 | + | 0.08 | 0.16 | 0.06 | 0.08
1200 | + | + | 0.16 | + | 0.08 | 0.05 | 0.03 | +
600 | + | + | + | + | 0.04 | 0.05 | 0.03 | +
300 | + | + | + | + | 0.02 | + | 0.02 | +
200 | + | + | + | + | + | 0.02 | + | +
150 | + | + | + | + | 0.01 | + | + | +
134 | 0.02 | + | 0.02 | + | + | + | + | +
110 | 0.02 | + | + | + | 0.01 | + | + | +
75 | + | + | + | + | + | + | + | +
50 | + | + | + | + | + | + | + | +

Baudrates that can be generated with the 80535 Internal Baudrate Generator:
MHz bps | 7.3728 | 11.0592 | 12.0000 | 14.7456 | 16.0000 | 18.0000 | 20.0000 | 24.0000
19200 |  |  |  |  |  |  |  | +
14400 |  |  |  |  |  | + |  |
12500 |  |  |  |  | 2.40 |  |  |
9600 |  |  | + |  |  |  |  | +
7200 |  |  |  |  |  | + |  |
4800 |  |  | + |  |  |  |  |

Baudrates that can be generated with the 80C515A Internal Baudrate Generator:
MHz bps | 7.3728 | 11.0592 | 12.0000 | 14.7456 | 16.0000 | 18.0000 | 20.0000 | 24.0000
460800 |  |  |  | + |  |  |  |
256000 |  |  |  |  | 2.34 |  |  | 2.34
230400 | + |  |  | + |  |  |  |
128000 |  |  | 2.34 |  | 2.34 |  | 2.34 | 2.34
115200 | + | + |  | + |  | 2.34 |  |
76800 | + |  | 2.34 | + |  |  | 1.73 | 2.34
64000 |  |  | 2.34 | 2.86 | 2.34 | 2.34 | 2.34 | 2.34
57600 | + | + |  | + | 3.55 | 2.34 | 1.36 | 0.16
38400 | + | + | 2.34 | + | 0.16 | 2.34 | 1.73 | 2.34
31250 |  | 0.54 | + | 1.70 | + | + | + | +
19200 | + | + | 2.34 | + | 0.16 | 1.02 | 1.36 | 0.16
14400 | + | + | 0.16 | + | 0.79 | 0.16 | 0.94 | 0.16
12500 | 2.40 | 1.26 | + | 0.37 | + | + | + | +
9600 | + | + | 0.16 | + | 0.16 | 0.69 | 0.16 | 0.16
7200 | + | + | 0.16 | + | 0.64 | 0.16 | 0.22 | 0.16
4800 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
3600 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
2400 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
1800 | + | + | 0.16 | + | 0.08 | 0.16 | 0.06 | 0.08
1200 | + | + | 0.16 | + | 0.08 | 0.05 | 0.03 | +
600 | + | + | + | + | 0.04 | 0.05 | 0.03 | +
300 | + | + | + | + | 0.04 | 0.05 | 1.73 |
200 | + | + | 0.05 |  |  |  |  |
150 | + |  |  |  |  |  |  |
134 | 0.03 |  |  |  |  |  |  |
110 | 2.27 |  |  |  |  |  |  |

Baudrates that can be generated with Timer 1 of the DALLAS 80C320:
MHz bps | 7.3728 | 11.0592 | 12.0000 | 14.7456 | 16.0000 | 18.0000 | 20.0000 | 24.0000
256000 |  |  |  |  | 2.34 |  |  |
230400 |  |  |  | + |  |  |  |
128000 |  |  |  |  | 2.34 |  |  | 2.34
115200 | + |  |  | + |  |  |  |
76800 |  |  |  | + |  |  | 1.73 | 2.34
64000 |  |  | 2.34 |  | 2.34 |  | 2.34 | 2.34
57600 | + | + |  | + |  | 2.34 |  |
38400 | + |  | 2.34 | + |  |  | 1.73 | 2.34
31250 |  |  | + |  | + | + | + | +
19200 | + | + | 2.34 | + | 0.16 | 2.34 | 1.73 | 2.34
14400 | + | + | 0.16 | + | 2.12 | 2.34 | 1.36 | 0.16
12500 | 2.40 | 1.26 | + | 2.40 | + | 2.17 | + | +
9600 | + | + | 2.34 | + | 0.16 | 1.02 | 1.36 | 0.16
7200 | + | + | 0.16 | + | 0.79 | 0.16 | 0.94 | 0.16
4800 | + | + | 0.16 | + | 0.16 | 0.69 | 0.16 | 0.16
3600 | + | + | 0.16 | + | 0.64 | 0.16 | 0.22 | 0.16
2400 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
1800 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
1200 | + | + | 0.16 | + | 0.16 | 0.16 | 0.16 | 0.16
600 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
300 | + | + | 0.16 | + | 0.08 | 0.16 | 0.22 | 0.16
200 | + | + | 0.16 | + | 0.16 | 0.16 | 1.73 |
150 | + | + | 0.16 | + |  |  |  |
134 | 0.20 | 0.03 | 0.09 |  |  |  |  |
110 | 0.26 | 2.27 |  |  |  |  |  |
75 | + |  |  |  |  |  |  |


ASEM-51 Release Notes

ASEM-51
RELEASE NOTES
December 31, 2002
Copyright © 1994, 1996, 2002 by W.W. Heinz
All rights reserved.

Version 1.3 Final | Dec 31, 2002
Version 1.3 Beta 3 | Jun 25, 2002
Version 1.2 | Jan 22, 1996
Version 1.1 | Oct 14, 1994
Version 1.0 | Sep 13, 1994

Copyright © 1994, 1996, 2002 by W.W. Heinz

Last revised: December 31, 2002


ASEM-51 V1.3 Release Notes

Version 1.3, Dec 31, 2002:

The following changes have been made to the ASEM-51 package, since version 1.3b3 (V1.3 Beta 3):

I. Bug Fixes

ASEM V1.3b3 flagged the following instructions

ADD A, direct
ADDC A, direct
SUBB A, direct
ANL A, direct
ORL A, direct
XRL A, direct
MOV A, direct
XCH A, direct
with the error message @@@@@ illegal operand @@@@@, if the direct expression started with a '('. The bug is fixed in ASEM V1.3.

When asem 1.3b3 tried to write to a busy character device under Linux, it aborted with an unspecific error message, e.g.

@@@@@ fatal I/O error 16: /dev/lp0 @@@@@
This is fixed in V1.3. The new runtime error message is looking like
@@@@@ device or resource busy: /dev/lp0 @@@@@

II. Support of 8051 Derivatives

With this version, new and updated processor definition files are provided:

File | Status | Manufacturer | Derivatives covered
C505.MCU | n | Infineon | C505-2R, C505-L
C505C.MCU | n | Infineon | C505C-2R, C505C-L
C505A.MCU | n | Infineon | C505A-4E, C505A-L
C505CA.MCU | n | Infineon | C505CA-4E, C505CA-L
C505L.MCU | n | Infineon | C505L
C508.MCU | n | Infineon | C508-4R, C508-4E
C868.MCU | n | Infineon | C868-1R, C868-1S
80C32X2.MCU | n | Philips | 80C31X2, 80C32X2, 80C51X2, 80C52X2, 80C54X2, 80C58X2, 87C51X2, 87C52X2, 87C54X2, 87C58X2, 89C51X2, 89C52X2, 89C54X2, 89C58X2

Status: n=new, r=renamed, m=modified, c=commented

Credits: Michael R. has sent me 80C32X2.MCU.

Version 1.3b3, June 25, 2002:

These are the longest release notes I have ever written for an ASEM-51 version. It seems that I had always some spare time to support, maintain, change, extend, improve and port it over and over for many years, but never to publish an official new release.
The release notes would become even more lengthy (and boring), if I only tried to explain the reasons I still remember. Let's say, ASEM-51 and its author simply are victims of circumstances! (smile)

  1. New Features
    1. Host Platforms
    2. Assembler
    3. MS-DOS Implementation
    4. Support of 8051 Derivatives
    5. Documentation

  2. Bug Fixes


ASEM-51 V1.2 Release Notes

Version 1.2, Jan 22, 1996:

1. Bug Fixes

Since version 1.0, only two serious bugs have been found in ASEM-51:

If DB or DW statements contained at least two subsequent expressions with forward references, followed by at least one further expression or string, the code lengths of these statements were calculated different on pass 1 and pass 2. Therefore, jumps to locations behind those statements might have led to wrong addresses.

If a symbol name with more than 31 characters was referenced in an instruction operand, the assembler marked that symbol reference with the error message @@@@@ symbol not defined @@@@@, although it was defined correctly above.

Apart of that, some minor deficiencies have been improved or corrected:

The arrows of the error messages in the list file are now pointing more exactly to the position in the source line, where something is wrong.

ASEM and HEXBIN do no longer crash in exotic I/O error situations (i.e. opening the door of a disk drive while reading from it), and they can output more specific I/O error messages.

It is no longer possible to overwrite the input files by specifying duplicate file names in the command line. (This does not apply to device names!)

The previous field separator '=' for ASEM and HEXBIN command line options had to be changed to ':', because of two reasons:
It is not possible to pass a string, containing an '=' character, to a DOS batch file as a parameter, and it cannot be assigned to a DOS environment variable.
However, the old field separator '=' is still accepted to maintain compatibility with previous HEXBIN versions.

2. New Features

The new assembler version comes up with numerous extensions and improvements:

The /INCLUDES command line option has been introduced to specify directories that ASEM has to search for include files.
The /DEFINE command line option has been implemented to define symbols from the command line, for easy assembly of different program variants.
Conditional assembly has been extended with the new IFDEF and IFNDEF meta instructions.
Primary controls may now be preceded also by general controls.
The new $PHILIPS control allows to switch to the reduced instruction set of the Philips 83C75x family of microcontrollers.
The pseudo instruction NAME has been introduced for compatibility purposes.
The ASEM-51 list file has been beautified, and contains more information. New fancy printing facilities have been introduced with the $XREF, $PAGEWIDTH, $DATE, $TITLE and $NOTABS controls.
The $DEBUG, $NODEBUG, $MOD51, $PAGING, $SYMBOLS, and $NOXREF controls have been implemented for compatibility purposes.
Now all assembler controls may be replaced by their (Intel-) abbreviations.

The error message filter program ASEM2MSG has been introduced, which allows the integration of ASEM-51 into the Borland IDE for DOS.
Files ASEM.PIF and ASEM.ICO have been added to simplify the ASEM-51 installation under Windows 3.1.

Device names that are passed to ASEM or HEXBIN as command line parameters may but need no longer be terminated with a ':' character.

HEXBIN 2.2 is running about 15% faster than version 2.1.
The length of the binary output file now matches exactly the byte count of the code.
HEXBIN now returns ERRORLEVEL 1 on conversion errors and ERRORLEVEL 2 on fatal runtime errors.

With this version, new processor definition files are provided:

File | Manufacturer | Derivatives
89C1051.MCU | Atmel | 89C1051, 89C2051
83C451.MCU | Philips | 83C451, 80C451, 87C451
83C528.MCU | Philips | 83C528, 80C528, 87C528, 83C524, 87C524, 83CE528, 80CE528, 89CE528
83C550.MCU | Philips | 83C550, 80C550, 87C550
83C562.MCU | Philips | 83C562, 80C562
83C652.MCU | Philips | 83C652, 80C652, 87C652, 83C654, 87C654, 83CE654, 80CE654
83C750.MCU | Philips | 83C750, 87C750
83C751.MCU | Philips | 83C751, 87C751
83C752.MCU | Philips | 83C752, 87C752
83C851.MCU | Philips | 83C851, 80C851
83C852.MCU | Philips | 83C852
C501.MCU | SIEMENS | C501-1R, C501-L
C502.MCU | SIEMENS | C502-2R, C502-L
C503.MCU | SIEMENS | C503-1R, C503-L
C511.MCU | SIEMENS | C511, C511A
C513.MCU | SIEMENS | C513, C513A, C513A-H
COM20051.MCU | SMC | COM20051

ASEM_51.DOC has been updated accordingly, and extended with an alphabetical 8051 instruction table. The error messages in appendices A and B are now sorted in lexical order, and completed with brief explanations.

The bootstrap program BOOT-51 V1.0 has been added to the ASEM-51 package. It allows an 8051 target system to receive an application program in Intel-Hex format over the serial interface, load it into the external RAM, and finally start it (provided that the board has a suitable memory map). Once installed, BOOT-51 leads to very short turn-around cycles in testing. For detailed information refer to the ASCII text file BOOT51.DOC provided.

An “ASEM-51 Updating Guide” has been added to the package. It describes, how and where to get a new ASEM-51 version! For further information see the ASCII file UPDATES.DOC provided.


ASEM-51 V1.1 Release Notes

Version 1.1, Oct 14, 1994:

Due to the zero feedback of the users (if any), bugs have neither been fixed nor found. However, there are some improvements all over the ASEM-51 package:

Many ASEM data structures have been revised.
In version 1.0 the assembler symbol table was implemented as an ordinary binary tree. With version 1.1 this has been replaced by an AVL tree that is kept balanced all the time, without loss of speed. Furthermore the memory consumption of the symbol table could be reduced by up to 25%.

HEXBIN has been optimized.
HEXBIN 2.1 now is running almost with twice the speed of version 2.0.

New stars are born!
That's why new processor definition files have been added to the ASEM-51 package:

80C320.MCU | DALLAS 25 MHz high-speed micro DS 80C320
83C515A.MCU | enhanced SIEMENS microcontroller SAB 80C515A/83C515A-5
83C517A.MCU | enhanced SIEMENS microcontroller SAB 80C517A/83C517A-5

ASEM_51.DOC has been updated accordingly and extended with an 8051 instruction table.


ASEM-51 V1.0 Release Notes

Version 1.0, Sep 13, 1994:

In the middle of September 94, we tried to post the first version of ASEM-51 in the Internet use-group “comp.binaries.ibm.pc”.
(Has anybody got it ???)


MCS-51 Microcontroller Family User's Manual

MCS® 51 Microcontroller Family User's Manual

The MCS® 51 Microcontroller Family User's Manual is an excellent tutorial for beginners and a valuable reference manual for experienced developers. It contains:

  • A general description of the Intel MCS-51 architecture
  • The complete MCS-51 core instruction set reference
  • Specifications of some popular 8051 derivatives

A must for all 8051 newbies!!!

It is available for free from Intel Corporation in Adobe Acrobat format. (15 MB)

Note: You will need the latest Acrobat Reader from Adobe Systems Inc.! (9 MB)

Get Acrobat Reader

Last revised: W.W. Heinz, March 13, 2002


The Intel OMF-51 Format

Intel has published a detailed specification of their OMF-51 object module format.
The last version 5.0 has been released in September 1982.

The original documents are provided in a very old, unknown text format.
However, I got a fair print-out with Microsoft Word 97.
Linux users can print them with Applixware Office.
If you fail to print or view the original files, you can read them online.
I have converted them to HTML as good as possible:

Generic Cover Letter for MCS-51 OMF EPS
External Product Specification for the MCS-51 Object Module Format

Last revised: W.W. Heinz, March 14, 2002


ASEM-51 Support

ASEM-51
SUPPORT
Version 1.3
December 31, 2002
Copyright © 1994, 1996, 2002 by W.W. Heinz
All rights reserved.

I. The ASEM-51 Support Website

If you want to

  • get the latest ASEM-51 version,
  • send bug reports, or
  • simply ask questions,

check out the ASEM-51 support website!
Presently the official home of ASEM-51 is

http://plit.de/asem-51/

If the URL has changed in the meantime (and things change quickly on the Internet), use a search-engine to find out the new ASEM-51 homepage.

II. Bug Reports

Although ASEM-51 is no brand-new product, it is probably not yet quite perfect! Whenever you experience problems with it, please do not hesitate to send a brief error report to

w.w.heinz@web.de

or write to the author's home address:

W.W. Heinz
Preuschwitzer Str. 97a
D-95445 Bayreuth
Germany

An error report should be written in English or German, and it should always contain the following information:

  • the user's full name and e-mail address
  • the ASEM-51 version number
  • the host platform (DOS, Windows, Linux)
  • a brief error description
  • a simplified 8051 demo program that shows the bug

If the program that causes the error, cannot be simplified to a short demo example, or in special cases, it may also be necessary to include one or more of the following files (if applicable):

  • original 8051 assembly source file
  • all include files
  • list file
  • Intel-HEX file and/or OMF-51 module
  • binary file (in case of HEXBIN errors)
  • capture file of console output (in case of runtime errors)
  • a detailed step-by-step description of how to reproduce the bug
  • your ASEM-51 distribution archive (in case it may be corrupted)
  • other associated files or information (if any)

In a particular situation, the user must decide himself, which information may be necessary (or helpful) to find and fix a bug. Whenever in doubt, attach more information than may be required!

Note: A bug that cannot be reproduced, cannot be fixed! bug

If you are new to the MCS-51 family or to ASEM-51, and you are not sure whether something striking is a bug or not, please report it regardless! If it is a bug, it will be fixed in the next release. If it is not, you'll always get an explanation from the author!

In most cases, the author and half a dozen beta testers cannot find all remaining bugs of a new release. Therefore, user feedback is a big chance for “living” free software. As time goes by, it may become more reliable than commercial products. Please support the freeware idea, and help to improve this program!

Copyright © 1994, 1996, 2002 by W.W. Heinz

Last revised: December 31, 2002


ASEM-51 Book-Shelf

Book-Shelf

book

Available Online-Documents:

  • License Agreement
  • ASEM-51 User's Manual
  • BOOT-51 User's Manual
  • ASEM-51 Release-Notes
  • MCS® 51 Microcontroller Family User's Manual
  • Specification of the Intel OMF-51 Format
  • ASEM-51 Support

Document Navigation

Some of the above documents are sets of HTML pages, which have been derived from a previous ASCII edition. Since ASCII files can only be read sequentially, these documents still have a corresponding structure. To ease the navigation, especially sequential reading, within a hypertext edition, a set of navigation buttons has been placed to the left of all HTML pages.

Last revised: W.W. Heinz, December 31, 2002

About this CHM file

Compiled by Henrik Haftmann, August 16, 2013.

Slight changes to HTML source files. CSS added.

The full source code for this .CHM file can be made available with any help decompiler software. The project source file (asem.hhp) is also included.


Introduction

I. Introduction

ASEM-51 is a two-pass macro assembler for the Intel MCS-51 family of microcontrollers.
It is running on the PC under MS-DOS, Windows and Linux.
The DOS real-mode assembler ASEM.EXE requires only 256 kB of free DOS memory and MS-DOS 3.0 (or higher).
The new protected-mode assembler ASEMX.EXE requires a 286 CPU (or better), and at least 512 kB of free XMS memory.
The new Win32 console-mode assembler ASEMW.EXE requires a 386 CPU (or better) and Windows 9x, NT, 2000 or XP.
The new Linux assembler asem requires a 386-based Linux system.
The new HTML documentation set requires a 90 MHz Pentium (or better) and a web browser.

The ASEM-51 assembly language is a rich subset of the Intel standard that guarantees maximum compatibility with existing 8051 assembler sources. ASEM-51 can generate two sorts of object files: Intel-HEX format, which is directly accepted by most EPROM programmers, and absolute OMF-51 format, which is required for many simulators, emulators and target debuggers. Thus ASEM-51 is suitable for small and medium MCS-51-based microcontroller projects in hobby, education and business. However, ASEM-51 has been designed to process also very large programs! Its most important features are:

  • fast, compact, reliable, easy to use, and well-documented
  • easy installation, almost no configuration required
  • command line operation, batch and networking capability
  • fully year 2000 compliant
  • DOS (RM and PM), Win32 and Linux binaries available
  • Intel-compatible syntax
  • five location counters, one for each of the MCS-51 address spaces
  • assembly-time evaluation of arithmetic and logical expressions
  • segment type checking for instruction operands
  • automatic code optimization of generic jumps and calls
  • macro processing (that really works)
  • nested include file processing
  • nested conditional assembly
  • absolute OMF-51 module output (with debug information)
  • Intel-HEX file output
  • hex-to-binary conversion utility
  • built-in symbols for 8051 special function registers (can be disabled)
  • direct support of more than seventy 8051 derivatives
  • support of user-defined 8051 derivatives
  • special support of the Philips 83C75x family
  • 8051 register bank support
  • detailed assembler listing with symbol table or cross reference
  • further fancy printing facilities (smile)
  • documentation in ASCII and HTML format
  • bootstrap program for testing on the MCS-51 target board
  • support for easy integration into the popular Borland IDE
  • limited update service by the author

The ASEM-51 software package has been developed with:

Borland-Pascal mit Objekten 7.0 © Borland International 1992
Delphi 2.0 Client/Server Suite © Borland International 1996
FreePascal 1.0.6 © Florian Klämpfl 2002


ASEM-51 V1.3 Host Platforms

I.1 Host Platforms

Version 1.3 is the first ASEM-51 release which is available for multiple host platforms. There are executables for MS-DOS, Win32 and Linux.
ASEM-51 V1.3 is distributed in two separate packages: one containing all the DOS/Windows stuff, and a second containing the Linux implementation.

MS-DOS and Windows:
Besides the proven real-mode assembler ASEM.EXE, version 1.3 contains the new protected-mode assembler ASEMX.EXE! ASEMX is functionally identical to ASEM, but it can use up to 64 MB of XMS memory to assemble even huge programs. ASEMX is accompanied by Borland's DPMI server DPMI16BI.OVL and runtime manager RTM.EXE. It requires a 286 CPU (or better), and at least 512 kB of free XMS memory (1 MB recommended)!
For Windows 9x/NT systems, the new Win32 console-mode assembler ASEMW.EXE is provided. ASEMW is functionally identical to ASEM, but it can handle long file names and benefits of the Win32 memory management. ASEMW is accompanied by a corresponding Win32 binary-to-hex converter HEXBINW.EXE.

Linux:
For 386-based Linux systems, the native ELF executables asem, hexbin, customiz, and reset51 are provided. These programs are Linux ports of the corresponding MS-DOS versions. Especially asem, hexbin, and reset51 had to be adapted to the Linux environment and its conventions. The rest of the ASEM-51 distribution has been made Linux-ready as good as possible. The Linux distribution is available in tar and rpm format.


ASEM-51 V1.3 Assembler

I.2 Assembler

With only five new keywords (MACRO, REPT, ENDM, EXITM, LOCAL) and some additional control characters, ASEM-51 version 1.3 introduces a full-blown macro processing! It is possible to define named and repeated macro blocks. Substitution of formal parameters is implemented as well as local symbols. Macro calls and definitions can be nested to any depth.
Conditional assembly has been extended with the new IFN, IFB, IFNB, ELSEIF, ELSEIFN, ELSEIFDEF, ELSEIFNDEF, ELSEIFB, and ELSEIFNB meta instructions.
The new control statements $GEN, $NOGEN, $GENONLY, $COND, $NOCOND, $CONDONLY, $SAVE, and $RESTORE allow refined listing options for macro expansion and conditional assembly. $MACRO and $NOMACRO allow or suppress macro expansion.

The /OMF-51 command line option has been introduced for the DOS and Windows implementations to generate absolute OMF-51 modules instead of Intel-HEX files. The Linux implementation recognizes the --omf-51 (or -o) option respectively. It is also possible to include debug information with the $DEBUG assembler control.

The environment variable ASEM51INC has been introduced on all platforms to specify a search path for include files.

The new $NOBUILTIN control suppresses predefined symbols (SFR) in the symbol table or cross-reference listing, while user-defined symbols are still listed.

The new $ERROR and $WARNING controls allow a more secure configuration management of application programs.

For identification of the assembler and its version number, the following predefined symbols of the type NUMBER have been introduced:

??ASEM_51 = 8051H ASEM-51
??VERSION = 0130H version 1.3

To improve compatibility with the Intel assembler, more than one assembler control is allowed in a control line now, e.g.:

$ NOMOD51 INCLUDE(80C517.MCU)

Include files may now be nested to any depth!

EQU and SET can now be used to define symbols not only for numerical constants, but also for registers A and R0 thru R7.


ASEM-51 V1.3 MS-DOS Implementation

I.3 MS-DOS Implementation

A batch file INSTALL.BAT has been provided to install or update the ASEM-51 package under MS-DOS or Windows.
The batch file KILLASEM.BAT deletes an existing ASEM-51 installation.

Due to a new parser concept and assembly language optimizations in lexical analysis and symbol table, ASEM.EXE is now running up to 20% faster.

ASEM and HEXBIN can now also read ASCII files in UNIX format!

The obsolete field separator '=' for ASEM and HEXBIN command line options is no longer accepted under MS-DOS. From version 1.3 only ':' is allowed.

The former RESET program has been renamed to RESET51, due to name conflicts. It can now also form a reset pulse by dropping the DTR signal of a serial port. BOOT51.DOC has been updated accordingly.


ASEM-51 V1.3 Support of 8051 Derivatives

I.4 Support of 8051 Derivatives

With this version, new and updated processor definition files are provided:

File | Status | Manufacturer | Derivatives covered
80C310.MCU | n | Dallas | DS80C310
80C390.MCU | n | Dallas | DS80C390
87C520.MCU | n | Dallas | DS87C520, DS83C520
87C530.MCU | n | Dallas | DS87C530, DS83C530
87C550.MCU | n | Dallas | DS87C550
89C420.MCU | n | Dallas | DS89C420
DS5000.MCU | n | Dallas | DS5000FP, DS5000, DS5000T, DS2250, DS2250T
DS5001.MCU | n | Dallas | DS5001FP, DS5002FP, DS5002FPM, DS2251T, DS2252T
MAX7651.MCU | n | Maxim | MAX7651, MAX7652
89C52.MCU | n | Atmel | AT89C52, AT89C55, AT89LV52, AT89LV55, AT87LV52, AT80F52, AT87F52
89C1051.MCU | n | Atmel | AT89C1051
89C2051.MCU | r | Atmel | AT89C2051, AT89C4051, AT89C1051U
89S8252.MCU | n | Atmel | AT89S8252, AT89LS8252
89S51.MCU | n | Atmel | AT89S51
89S52.MCU | n | Atmel | AT89S52, AT89LS52
89S53.MCU | n | Atmel | AT89S53, AT89LS53
89S4D12.MCU | n | Atmel | AT89S4D12
87F51RC.MCU | n | Atmel | AT87F51RC, AT87F55, AT87LV55
83C51R.MCU | n | Intel | 83C51RA, 80C51RA, 87C51RA, 83C51RB, 87C51RB, 83C51RC, 87C51RC
83C51FX.MCU | r, m, c | Intel | 83C51FA, 80C51FA, 87C51FA, 83C51FB, 87C51FB, 83C51FC, 87C51FC
83C51KB.MCU | n | Intel | 83C51KB
83C51GB.MCU | n | Intel | 83C51GB, 80C51GB, 87C51GB
83C151.MCU | n | Intel | 83C151SB, 87C151SB, 80C151SB, 83C151SA, 87C151SA
83931HA.MCU | n | Intel | 83931HA, 80931HA
83931AA.MCU | n | Intel | 83931AA, 80931AA
83C750.MCU | m | Philips | 83C750, 87C750
83C754.MCU | n | Philips | 83C754, 87C754
87LPC762.MCU | n | Philips | 87LPC762
87LPC768.MCU | n | Philips | 87LPC768
83C515A.MCU | m | SIEMENS | 83C515A-5, 80C515A
C504.MCU | n, c | SIEMENS | C504-2R, C504-L
C509.MCU | n, c | SIEMENS | C509-L
C513AO.MCU | n | SIEMENS | C513AO
C515.MCU | n | SIEMENS | C515-L, C515-1R
C515A.MCU | n | SIEMENS | C515A-L, C515A-4R
C515C.MCU | n, c | SIEMENS | C515C-8R
C517A.MCU | r, m | SIEMENS | C517A-L, C517A-4R, 83C517A-5, 80C517A
C540U.MCU | n | SIEMENS | C540U
C541U.MCU | n | SIEMENS | C541U
83C154S.MCU | n | OKI | 83C154S, 80C154S, 85C154HVS
73M2910.MCU | n | TDK | 73M2910, 73M2910A
AN2131.MCU | n | Cypress | AN2121, AN2122, AN2125, AN2126, AN2131, AN2135, AN2136

Status: n=new, r=renamed, m=modified, c=commented

File 83C51F.MCU has been renamed to 83C51FX.MCU and completed with the “mysterious IPH register” and related commentary.
The SFR symbol definitions in file 83C750.MCU have been changed according to manufacturer specifications.
The BIT symbols for P1.0 thru P1.3 in file 83C515A.MCU have been changed according to their equivalents in the new file C515C.MCU.
File C517A.MCU replaces 83C517A.MCU, because the C517A is functionally identical (with some slight differences in naming conventions only).
Note that all SIEMENS derivatives are now manufactured and sold by Infineon!

Credits:
Axel Kielhorn has written the file DS5000.MCU.
Anders Sandström has sent me 87LPC762.MCU and 87LPC768.MCU.


ASEM-51 V1.3 Documentation

I.5 Documentation

The whole documentation is now available in both ASCII and HTML format!
(To read the HTML manuals, start with file DOCS.HTM.)
The previous “ASEM-51 Updating Guide” UPDATES.DOC has been replaced by the document SUPPORT.DOC with the title “ASEM-51 Support”.
Of course the whole ASEM-51 documentation has been updated to describe all new features.


ASEM-51 V1.3 New Features

I. New Features

Version 1.3 is a release of extensions indeed!
That's why the new features are discussed first.
  1. Host Platforms
  2. Assembler
  3. MS-DOS Implementation
  4. Support of 8051 Derivatives
  5. Documentation


ASEM-51 V1.3 Bug Fixes

II. Bug Fixes

An attempt to redefine a predefined (SFR) symbol with the /DEFINE command line option was sometimes sufficient to totally confuse ASEM V1.2! In these cases, version 1.3 now aborts with a proper runtime error message.

ASEM V1.2 didn't notice, if number type operands of control statements were not enclosed in parentheses. This has been fixed with version 1.3!

If the location counter symbol $ appeared as the first operand of an instruction starting in column 1, ASEM V1.2 has flagged it with the error message

   25:    0007  80 00           SJMP $
                                     ^
                          @@@@@ illegal control statement @@@@@

This has been fixed with version 1.3!

ASEM V1.3 does no longer accept the following constructions:

  • The start of absolute BIT or DATA segments with BSEG or DSEG at base addresses above 7FH.
  • Memory reservation statements in BIT or DATA segments with DBIT or DS at locations above 7FH.
  • Setting the location counter in BIT or DATA segments with ORG to locations above 7FH.
  • Setting the location counter with ORG to locations below the segment base address. (Applies to all segments!)

If the first operand of the following instructions

        ANL direct, #const8
        ORL direct, #const8
        XRL direct, #const8
        MOV direct, #const8
        MOV direct, direct
        DB  const8, const8
        DW  const16, const16
contained forward references on pass 1, and was flagged with one of the following error messages
        @@@@@ segment type mismatch @@@@@
        @@@@@ attempt to divide by zero @@@@@
        @@@@@ invalid bit number @@@@@
        @@@@@ invalid base address @@@@@
        @@@@@ expression out of range @@@@@
on pass 2, ASEM V1.2 calculated the code lengths of these instructions different on pass 1 and pass 2, causing a
        @@@@@ phase error @@@@@
for all subsequent label definitions in the same CODE segment. This has been fixed with version 1.3!

If a frequently used special character like # or @ is read in a position where an expression is expected, ASEM V1.3 does no longer flag it with the confusing error message “unary operator expected”, but with ”illegal operand”.

If ASEM.EXE V1.2 had aborted with a runtime error on pass 1, the previous HEX and list files were left unchanged, because the old output files were first overwritten between pass 1 and pass 2. In some cases this was very confusing for the users (and for batch files as well).
Provided the command line parameters are correct, the old output files are now overwritten by version 1.3 prior to pass 1.

The processor definition file 89C1051.MCU, provided with version 1.2, was containing the definitions for the AT89C2051 rather than for the AT89C1051! Since the two parts are not register-compatible, 89C1051.MCU has been renamed to 89C2051.MCU, and 89C1051.MCU has been rewritten.

Sometimes BOOT-51 V1.0 lost characters, if the ”GO TO” command was sent in batch mode with baudrates greater than 9600 Baud. This has been fixed with version 1.1.
BOOT-51 V1.1 is now accepting Intel-HEX file uploads with CR, LF, or CR/LF at the end of line.
BOOT51.DOC has been updated accordingly.

Due to a limitation of the Turbo-Pascal 7.01 runtime system, the program RESET.EXE crashed with ”Runtime error 200” on 200 MHz (and faster) Pentium systems! This has been fixed with release 1.3.
Note: The program has been renamed to RESET51.EXE to avoid name conflicts.

When assembling short programs on fast computers and uploading them to the MCS-51 target board at low baudrates with BOOT.BAT, it could happen that the upload of the HEX file started before BOOT-51 had fully recovered from (an automatic) reset. Since BOOT-51 needs some time to output its sign-on message and prompt, it sometimes missed the upload command, because ASEM.EXE had finished too fast! (smile)
To fix this, a small delay program SLEEP.EXE is provided, which is always invoked after RESET51.EXE. (see UPLOAD.BAT)