home *** CD-ROM | disk | FTP | other *** search
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
-
-
-
- <<< Z80ASMDD.DOC >>>
-
-
- by Dianna Dearborn September 12,1987
-
-
- This document outlines a number of fixes and enhancements to
- Z80ASM 2.0 and identifies remaining the bugs that I'm aware of.
-
- FIXES:
-
- -in JR and DJNZ relative addressing instruction operands to allow
- the use of symbolic label references
-
- -in JR and DJNZ instructions to allow the use of the $ symbol to
- represent current reference counter value.
-
- -in the LABEL: character validation test to allow the use of the
- $ symbol in labels
-
- -in valid label test and error reporting routine
-
- -in the "IBM" pseudo-op
-
- ENHANCEMENTS:
-
- -in JR and DJNZ instructions, a displacement range test was added
- to trap operand expression which evaluated outside the -126 to
- +129 byte limits.
-
- -a routine was added to eliminate the initial page eject on the
- listing output
-
- REMAINING BUGS:
-
- -in reserved word test for LABELS:
-
- -in the reference value of the last LABEL: used in a source file.
-
- OTHER:
-
- -a discussion is included on some of the syntax rules of Z80ASM
- discovered along the way.
-
-
- BACKGROUND:
-
- Some weeks ago, I started to do some serious Z80 assembly
- language programming. I downloaded a copy of Z80ASM from a RCP/M
- and started to write code. My programs crashed immediately.
-
- First thing that happened was the assembler got caught in an
-
-
- 5
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
- infinite loop and hung up. I narrowed that down to the use of a
- dollar $ign in label names.
-
- Second, there was a bug when using the dollar $ign symbol
- convention to indicate the current value of the reference counter
- in operand expressions in JR and DJNZ relative addressing
- instructions, ie., "JR $+12H"; it worked as expected in JP and
- CALL instructions. I found that using "JR +12H" would work.
-
- Finally, using LABLES: in the operands of JR as DJNZ
- instructions crashed, (ie., JR LOOP). Again, they worked with
- JP and CALL operands. I found no way around this bug. I was
- left with the choice of either counting the number of bytes of
- intervening instructions to calculate the relative offsets (too
- much work, prone to error and difficult to modify) or using only
- JP instructions. Neither was acceptable so I started to debug
- the assembler.
-
- THE BUGS AND THE FIXES:
-
- $ in LABLE$: was indeed an infinite loop probably caused by
- a typo in the original source code. The fix was simply to patch
- in the proper address in the JP instruction.
-
- Relative displacement errors were caused by a complete lapse
- of thought in the mind of the programmer. While evaluating the
- operand expressions, JP and CALL instructions create a two byte
- operand that is the absolute destination address of the jump.
- Z80ASM handles them by getting the reference counter of the
- current instruction, in the case of "JP $+12H", and adding to it
- the value of the expression, and in the case of "JP LABEL:", by
- getting the address of the label from the symbol table and
- placing it in the operand. Both methods are combined in such
- instructions as "JP LABEL:+12H".
-
- JR and DJNZ relative addressing instructions were handled in
- the same manor by the same routine as the absolute addressing
- instructions and the seemingly random displacement values in
- their operands turned out to be the low byte of the absolute
- address of the instruction's destination. Relative addressing
- instructions require that the signed DIFFERENCE between the
- current address and the destination address be placed in the
- operand which will then be added to the PROGRAM COUNTER of the
- Z80 prior to the jump. To accomplish this, I had to add code to
- Z80ASM.
-
- After fixing these three bugs, I found that there was, of
- course, no trap for displacement range errors. This creates the
- possibility of writing an operand expression that evaluates
- out of range but looks correct upon cursory examination and then
- sends your program to never-never land. These errors can be
- quite difficult to detect. I added a range test that is
- performed after the evaluation of the operand expression and used
- the $ symbol, appropriately enough, to flag assembly listing
- lines with range errors then forced the operand to 00.
-
-
- 6
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
-
- Along the way I discovered that the reserved word and valid
- label length tests did not seem to work. The labels were only
- tested on the first pass to validate them before putting them
- into the symbol table but the results were not saved for the
- second pass. I changed the routine so that now at least the
- label length is tested on the second pass and the results are
- passed on to the listing, however, using a reserved word or
- defining a label twice will still cause your program to crash!
- without warning you of the error.
-
- What actually happens is that on the first pass when a
- reserved word or redefined label is detected, the label is not
- added to the symbol table and the reference counter is not
- updated. On the second pass, the error goes undetected, the op
- code and operand are evaluated, the reference counter is updated
- and all symbolic addresses from the line in error are off by the
- number of bytes in the op code of the error line. I thought
- about disabling the test altogether, however, this type of error
- is easier to detect than one line with a reserved word where it
- doesn't belong because every symbolic reference pass the bad line
- points to a wrong address. The fix is messy and I need to get on
- with my project so I'll save this one for another day -- at least
- you were warned!!
-
- The other remaining label error has to do with the last
- label used in the assembly. For some reason, the reference
- address (or EQUate value) of the last entry in the symbol table
- gets trashed and, when referenced, will give erroneous results.
- the way around that is to make sure that the last label used does
- not get referenced. I do this by labeling the 'END' statement.
- My last line in the assembly is usually:
-
- THEEND END 100H
-
- Again, I'll fix this bug when I get more time to work on it.
-
- While plowing through the Z80ASM code I found a new to me
- pseudo-op called "IBM". It turned out to be an ascii $tring
- formating instruction for messages. The routine had three major
- bugs and I'm certain that it was never tested after it was
- written. I sorted it out to what I think the programmer had in
- mind. Anyhow, it now works according to the syntax rules
- discussed below.
-
- And, lastly, the initial page eject for the listing was a
- real irritation to me. I tested for page 1 and skipped the form
- feed in the header. The page number is stored as one byte of two
- BCD digits (maximum of 99) and "rolls over" at page 100 to 00.
- If your program is more than 100 pages long, then page 101 will
- not eject but page 102 will catch up. This is untested and
- probably will remain so!!
-
- Principally, I tried to keep Z80ASM in tact as much as
- possible. In some places, I corrected the original code without
-
-
- 7
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
- altering the rest of the routine. In the label routine, I altered
- the order of routine and changed only the JP addresses. The rest
- of the changes required the addition of new code. To make room
- for the new code, I moved the main look-up table at the end of
- the program to higher memory, staying within the last page, and
- added the new routines to the end of the program.
-
-
- TESTING:
-
- I've tried to test Z80ASMDD thoroughly with benchmark
- programs and others that I've written, however, I am sure that
- the original programmer thought he (she?) did also -- at least
- well enough to write a bigger and better assembler. So help me.
- Run the assembler on some of your successful programs and compare
- them. If there is any bugs, please let me know. I'll try to fix
- all of the real ones.
-
- EPILOG:
-
- This was fun for me (she's crazy!!). I didn't know the
- insides of assemblers before I started and now I have an
- appreciation for both assemblers in general and, particularly,
- the work of 'LCS' -- I learned a lot! I suppose the ultimate
- irony, after all this work, would be someone telling me that
- there is a more effecient, fully featured, bug-free assembler
- readily available in the public domain!!
-
- I have one more feature to add when I have time -- I feel
- lost without a symbol table so I'll dump that to the listing some
- day. The way I get around that now is call DDT with a null
- program and check out the symbol table left in memory starting at
- 22A2H.
-
- About the version number, I worked it up to 2.4 to keep
- track of my work and, vainly enough, added my initials to
- easily identify this version with the fixes from any others in
- RCP/M land.
-
- From the skeletons left in the code, it's become obvious that
- other features were planned for Z80ASM but never implemented.
- Maybe I'll work on them some day. Perhaps add a routine to allow
- lower case alpha enclosed in quotes. If you have any ideas for
- new features or know of other bugs, please share them with me and
- I'll see what I can do.
-
- I'd like to hear from any users of this version -- tell me
- about your experiences, both the good and the bad. Send E-mail
- to:
-
- DIANNA DEARBORN
- DATA TECH RCP/M 408-238-9621.
- SAN JOSE, CA.
-
-
-
-
- 8
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
-
- NOTES ON SYNTAX FOR Z80ASM-DD 2.4
-
- DISCRIPTION OF Z80ASM:
-
- Z80ASM is a two pass assembler. The first pass creates the
- symbol table and the second pass does the assembly. The
- assembler accepts as input an <filename>.ASM source file written
- in ZILOG assembly language and outputs both an Intel formatted
- <filename.HEX> object file and an assembly listing to the
- printer in real time, either of which may be disabled. This
- assembler does not create any intermediate files, <filename.PRN>
- or <filename.SYM> files.
-
- The symbol table is created starting at 22A2H and may be expanded
- up to CCP base without harm. There is no trap for symbol tables
- that overwrite CCP. The maximum number of symbolic entries is
- dependent on memory available with the system configuration and
- the aggregate length of each symbol plus 4 bytes per symbol.
-
- All program I/O is done through FDOS calls to 0005H. All read,
- write and working buffers, except the symbol table, are internal
- to the program. This assembler was written in 8080 assembly
- language probably as a bootstrap to writing a more effecient and
- fully featured Z80 assembler.
-
- INVOKING Z80ASM: The format is:
-
- A>Z80ASM <filename>[.LH ]
-
- The assembler expects an input source file named <filename>.ASM.
- The optional .LH extension is the (L)isting output and (H)ex file
- output defeat option mechanism. The true state of the option
- (defeated) is invoked by typing 'N' in the appropriate location,
- any other character enables the function. Without the extension
- both Listing output and Hex file output functions are enabled.
- When the listing function is disabled, only assembly line errors
- will be listed. For example:
-
- <filename>.N will disable the listing function but
- create a <filename>.HEX file as output.
- <filename>.xN will disable the .HEX file output but
- a listing is printed. Where x is any
- permissible CP/M .typ char except a space
-
- SOURCE CODE FILE LIMITATIONS:
-
- Source code files may be of any length acceptable to CP/M,
- however, there is a practical limit to the size of the symbol
- table which is not written to a file but held in memory between
- 22A2H and CCP base.
-
-
-
-
-
-
- 1
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
- SOURCE CODE LINES:
-
- Source code lines may not exceed 80 characters including CR & LF
- and must be terminated by LF (0AH). Most routines test for CR to
- exit.
-
- LOWER/UPPER CASE TRANSLATION:
-
- Presently, ALL lower case ascii characters are translated to
- upper case, including strings enclosed by single quote marks.
-
- OPCODES AND OPERANDS:
-
- Opcodes may NOT start in column 1. Opcodes and their operands
- follow the rules established by Zilog in the Z80-Assembly
- Language Programming Manual.
-
- RESERVED WORDS:
-
- Certain symbolic names are reserved as key words in the operand
- fields. They are:
-
- Register names: A, B, C, D, E, H, L, AF, BC, DE, HL, AF'
- Flag Conditions: C, NC, Z, NZ, M, P, PO, PE
-
- Using a reserved word as a smybolic reference in the operand
- field will give erroneous operand values.
-
- EXPRESSIONS:
-
- Expressions are operand entries and may be unary (single term) or
- binary. Elements of the expression are connected by the
- arithmetic operators + (addition), - (subtraction) , and *
- (multiplication).
-
- Expression elements may be numbers which begin with a numeric
- digit, symbolic references which begin with an alpha charater
- (LABELS: and EQUates), $ symbol for the current value of the
- reference counter and a single ascii character enclosed in single
- quote marks which equates to a hexadecimal number. Expressions
- are terminated by any other characters, usually a space or comma.
-
- Expressions are evaluated from left to right, parentheses are not
- permitted. Expression evaluation results are limited to 2 bytes
- (16 bits) in length with a maximum unsigned value of 65,535.
-
- NUMBERS:
-
- Numbers MUST begin with a numeric digit, leading zeroes will
- suffice. Numbers may be written in hexadecimal, decimal or
- binary bases. Hexadecimal numbers must be followed immediately
- by the 'H' radix indicator, Binary numbers must be followed
- immediately by the 'B' radix indicator. Decimal numbers are not
- followed by a radix letter indicator.
-
-
-
- 2
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
- LABELS:
-
- Labels MUST start in column 1. A label is a string of one or
- more characters and must begin with an alpha character. Valid
- characters are A-Z, 0-9, $, period (.) and trailing colon (:).
- Labels are terminated by any other character, usually a space or
- comma. Labels may be up to 11 characters in length (excluding
- colons), all characters are unique. Trailing colons are optional
- and ignored by the assembler (ie., LABELS: = LABELS ). Labels
- may not be a reserved word. Examples of valid labels are:
-
- LABEL LABEL: LABEL$ LONG.LABEL LONGERLABEL
-
- WARNING: at present the reserved word trap does not work.
- An opcode or reserved word in an expression or starting in
- column 1 will cause your program to crash! Also, the last
- label stored in the symbol table will give erroneous values,
- therefore, DO NOT reference the last label in the body of a
- program.
-
-
- PSEUDO-OPS:
-
- Pseudo-ops are instructions to the assembler and as such do not
- generate object code. Psuedo-ops are summerized below:
-
- ORG e Sets the reference counter to the value of
- expression e.
-
- EQU e Sets the value of a label to e. Can occur
- only once per label.
-
- END e Signifies the end of source code -- all code
- after END is ignored. Expression e evaluates
- to the program starting address for .HEX
- files loaded with LOAD (e = 100H is normal)
-
- EJECT Forces a new page in listing.
-
- DEFS e Reserves e bytes of memory. Advances
- reference counter RC = RC + e.
-
- DEFB e Defines one byte of memory to equal value e.
-
- DEFB '$tring' Defines n bytes of memory as the ascii
- equivalent of the characters in the $tring
- enclosed by single quote marks. n
- equals the number of chars in the string.
-
- DEFW e Defines two bytes of memory to be equal to
- the value of e. e is stored in memory as low
- byte -- high byte, ie., CRLF EQU 0D0AH...
- DEFW CRLF... produces 0A, 0D in consecutive
- bytes of memory.
-
-
-
- 3
-
-
-
-
-
- Z80ASM-DD 2.4 ---> FIXES TO Z80ASM-2.0 DD 9/12/87
-
-
- IBM e Defines n bytes of memory as the hex equiva-
- lent of the ascii elements in the expression
- e where n is the number of elements and takes
- the form:
-
- IBM c1,c2,'$tring',c3,...,cn
-
- where values of c are the hex representation
- of ascii characters without base indicator
- (H) and elements are seperated by a comma.
- Strings are enclosed by single quotes and
- each character of a string is considred an
- element. Single quotes may be included by
- defining cx = 27 (H). Symbolic equivalents
- are not allowed (ie., CR EQU 0DH...IBM
- CR,..). e is terminated by a CR. Usage
- example, a $ terminated message:
-
- IBM 0D,0A,'MESSAGE',0D,0A,'$'
-
- where e is an expression as defined above.
-
- MACRO, CONDitional, EXTERNAL and GLOBAL pseudo-ops and LOGICAL
- operators are not implemented in this version of Z80ASM.
-
- COMMENT LINES:
-
- Comment lines are defined as any string following a semicolon (;)
- in a line. Comments may start in any column and are ignored by
- the assembler.
-
- ASSEMBLER ERROR MESSAGES:
-
- Assembly error messages are one character codes which are placed
- in the first column of the line containing the error in the
- output listing.
-
- L Label length error -- label > 11 characters long
-
- M Label is either a reserved word or previously defined (not
- implemented in version 2.4)
-
- O "Overflow" -- indicates that the op code as spelled was
- not found in reference table.
-
- U Undefined label in the operand field
-
- $ Displacement range error -- range = -127 < expression <+130
-
- DD
-
-
-
-
-
-
-
- 4
-
-
-
-
-