home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / z80asm24.lbr / Z80ASM24.DZC / Z80ASM24.DOC
Encoding:
Text File  |  1987-10-13  |  21.1 KB  |  529 lines

  1.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  2.  
  3.  
  4.  
  5.  
  6.  
  7.                             <<<   Z80ASMDD.DOC   >>>
  8.  
  9.  
  10.         by Dianna Dearborn                               September 12,1987
  11.  
  12.  
  13.         This document outlines a number of fixes and enhancements to
  14.         Z80ASM 2.0 and identifies remaining the bugs that I'm aware of.
  15.  
  16.         FIXES:
  17.  
  18.         -in JR and DJNZ relative addressing instruction operands to allow
  19.          the use of symbolic label references
  20.  
  21.         -in JR and DJNZ instructions to allow the use of the $ symbol to
  22.          represent current reference counter value.
  23.  
  24.         -in the LABEL: character validation test to allow the use of the
  25.          $ symbol in labels
  26.  
  27.         -in valid label test and error reporting routine
  28.  
  29.         -in the "IBM" pseudo-op
  30.  
  31.         ENHANCEMENTS:
  32.  
  33.         -in JR and DJNZ instructions, a displacement range test was added
  34.          to trap operand expression which evaluated outside the -126 to
  35.          +129 byte limits.
  36.  
  37.         -a routine was added to eliminate the initial page eject on the
  38.          listing output
  39.  
  40.         REMAINING BUGS:
  41.  
  42.         -in reserved word test for LABELS:
  43.  
  44.         -in the reference value of the last LABEL: used in a source file.
  45.  
  46.         OTHER:
  47.  
  48.         -a discussion is included on some of the syntax rules of Z80ASM
  49.         discovered along the way.
  50.  
  51.  
  52.         BACKGROUND:
  53.  
  54.              Some weeks ago, I started to do some serious Z80 assembly
  55.         language programming.  I downloaded a copy of Z80ASM from a RCP/M
  56.         and started to write code.  My programs crashed immediately.
  57.  
  58.              First thing that happened was the assembler got caught in an
  59.  
  60.  
  61.                                         5
  62.  
  63.  
  64.  
  65.  
  66.  
  67.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  68.  
  69.  
  70.         infinite loop and hung up.  I narrowed that down to the use of a
  71.         dollar $ign in label names.
  72.  
  73.              Second, there was a bug when using the dollar $ign symbol
  74.         convention to indicate the current value of the reference counter
  75.         in operand expressions in JR and DJNZ relative addressing
  76.         instructions, ie., "JR    $+12H"; it worked as expected in JP and
  77.         CALL instructions.  I found that using  "JR   +12H"  would work.
  78.  
  79.              Finally,  using LABLES: in the operands of JR as DJNZ
  80.         instructions crashed, (ie., JR    LOOP).  Again, they worked with
  81.         JP and CALL operands.  I found no way around this bug.  I was
  82.         left with the choice of either counting the number of bytes of
  83.         intervening instructions to calculate the relative offsets (too
  84.         much work, prone to error and difficult to modify) or using only
  85.         JP instructions.  Neither was acceptable so I started to debug
  86.         the assembler.
  87.  
  88.         THE BUGS AND THE FIXES:
  89.  
  90.              $ in LABLE$: was indeed an infinite loop probably caused by
  91.         a typo in the original source code.  The fix was simply to patch
  92.         in the proper address in the JP instruction.
  93.  
  94.              Relative displacement errors were caused by a complete lapse
  95.         of thought in the mind of the programmer.  While evaluating the
  96.         operand expressions, JP and CALL instructions create a two byte
  97.         operand that is the absolute destination address of the jump.
  98.         Z80ASM handles them by getting the reference counter of the
  99.         current instruction, in the case of "JP  $+12H", and adding to it
  100.         the value of the expression, and in the case of "JP  LABEL:", by
  101.         getting the address of the label from the symbol table and
  102.         placing it in the operand.  Both methods are combined in such
  103.         instructions as "JP  LABEL:+12H".
  104.  
  105.              JR and DJNZ relative addressing instructions were handled in
  106.         the same manor by the same routine as the absolute addressing
  107.         instructions and the seemingly random displacement values in
  108.         their operands turned out to be the low byte of the absolute
  109.         address of the instruction's destination.  Relative addressing
  110.         instructions require that the signed DIFFERENCE between the
  111.         current address and the destination address be placed in the
  112.         operand which will then be added to the PROGRAM COUNTER of the
  113.         Z80 prior to the jump.  To accomplish this, I had to add code to
  114.         Z80ASM.
  115.  
  116.              After fixing these three bugs, I found that there was, of
  117.         course, no trap for displacement range errors.  This creates the
  118.         possibility of writing an operand expression that evaluates
  119.         out of range but looks correct upon cursory examination and then
  120.         sends your program to never-never land.  These errors can be
  121.         quite difficult to detect.  I added a range test that is
  122.         performed after the evaluation of the operand expression and used
  123.         the $ symbol, appropriately enough, to flag assembly listing
  124.         lines with range errors then forced the operand to 00.
  125.  
  126.  
  127.                                         6
  128.  
  129.  
  130.  
  131.  
  132.  
  133.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  134.  
  135.  
  136.  
  137.              Along the way I discovered that the reserved word and valid
  138.         label length tests did not seem to work.  The labels were only
  139.         tested on the first pass to validate them before putting them
  140.         into the symbol table but the results were not saved for the
  141.         second pass.  I changed the routine so that now at least the
  142.         label length is tested on the second pass and the results are
  143.         passed on to the listing, however, using a reserved word or
  144.         defining a label twice will still cause your program to crash!
  145.         without warning you of the error.
  146.  
  147.              What actually happens is that on the first pass when a
  148.         reserved word or redefined label is detected, the label is not
  149.         added to the symbol table and the reference counter is not
  150.         updated.  On the second pass, the error goes undetected, the op
  151.         code and operand are evaluated, the reference counter is updated
  152.         and all symbolic addresses from the line in error are off by the
  153.         number of bytes in the op code of the error line.  I thought
  154.         about disabling the test altogether, however, this type of error
  155.         is easier to detect than one line with a reserved word where it
  156.         doesn't belong because every symbolic reference pass the bad line
  157.         points to a wrong address. The fix is messy and I need to get on
  158.         with my project so I'll save this one for another day -- at least
  159.         you were warned!!
  160.  
  161.              The other remaining label error has to do with the last
  162.         label used in the assembly.  For some reason, the reference
  163.         address (or EQUate value) of the last entry in the symbol table
  164.         gets trashed and, when referenced, will give erroneous results.
  165.         the way around that is to make sure that the last label used does
  166.         not get referenced.  I do this by labeling the 'END' statement.
  167.         My last line in the assembly is usually:
  168.  
  169.                               THEEND    END    100H
  170.  
  171.              Again, I'll fix this bug when I get more time to work on it.
  172.  
  173.              While plowing through the Z80ASM code I found a new to me
  174.         pseudo-op called "IBM".  It turned out to be an ascii $tring
  175.         formating instruction for messages.  The routine had three major
  176.         bugs and I'm certain that it was never tested after it was
  177.         written.  I sorted it out to what I think the programmer had in
  178.         mind.  Anyhow, it now works according to the syntax rules
  179.         discussed below.
  180.  
  181.              And, lastly, the initial page eject for the listing was a
  182.         real irritation to me.  I tested for page 1 and skipped the form
  183.         feed in the header.  The page number is stored as one byte of two
  184.         BCD digits (maximum of 99) and "rolls over" at page 100 to 00.
  185.         If your program is more than 100 pages long, then page 101 will
  186.         not eject but page 102 will catch up.  This is untested and
  187.         probably will remain so!!
  188.  
  189.              Principally, I tried to keep Z80ASM in tact as much as
  190.         possible.  In some places, I corrected the original code without
  191.  
  192.  
  193.                                         7
  194.  
  195.  
  196.  
  197.  
  198.  
  199.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  200.  
  201.  
  202.         altering the rest of the routine. In the label routine, I altered
  203.         the order of routine and changed only the JP addresses.  The rest
  204.         of the changes required the addition of new code.  To make room
  205.         for the new code, I moved the main look-up table at the end of
  206.         the program to higher memory, staying within the last page, and
  207.         added the new routines to the end of the program.
  208.  
  209.  
  210.         TESTING:
  211.  
  212.              I've tried to test Z80ASMDD thoroughly with benchmark
  213.         programs and others that I've written, however, I am sure that
  214.         the original programmer thought he (she?) did also -- at least
  215.         well enough to write a bigger and better assembler.  So help me.
  216.         Run the assembler on some of your successful programs and compare
  217.         them.  If there is any bugs, please let me know.  I'll try to fix
  218.         all of the real ones.
  219.  
  220.         EPILOG:
  221.  
  222.              This was fun for me (she's crazy!!).  I didn't know the
  223.         insides of assemblers before I started and now I have an
  224.         appreciation for both assemblers in general and, particularly,
  225.         the work of 'LCS' -- I learned a lot!  I suppose the ultimate
  226.         irony, after all this work, would be someone telling  me that
  227.         there is a more effecient, fully featured, bug-free assembler
  228.         readily available in the public domain!!
  229.  
  230.              I have one more feature to add when I have time -- I feel
  231.         lost without a symbol table so I'll dump that to the listing some
  232.         day.  The way I get around that now is call DDT with a null
  233.         program and check out the symbol table left in memory starting at
  234.         22A2H.
  235.  
  236.              About the version number, I worked it up to 2.4 to keep
  237.         track of my work and, vainly enough, added my initials to
  238.         easily identify this version with the fixes from any others in
  239.         RCP/M land.
  240.  
  241.              From the skeletons left in the code, it's become obvious that
  242.         other features were planned for Z80ASM but never implemented.
  243.         Maybe I'll work on them some day.  Perhaps add a routine to allow
  244.         lower case alpha enclosed in quotes.  If you have any ideas for
  245.         new features or know of other bugs, please share them with me and
  246.         I'll see what I can do.
  247.  
  248.              I'd like to hear from any users of this version -- tell me
  249.         about your experiences, both the good and the bad.  Send E-mail
  250.         to:
  251.  
  252.                        DIANNA DEARBORN
  253.                        DATA TECH RCP/M  408-238-9621.
  254.                        SAN JOSE, CA.
  255.  
  256.  
  257.  
  258.  
  259.                                         8
  260.  
  261.  
  262.  
  263.  
  264.  
  265.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  266.  
  267.  
  268.  
  269.                         NOTES ON SYNTAX FOR Z80ASM-DD 2.4
  270.  
  271.         DISCRIPTION OF Z80ASM:
  272.  
  273.         Z80ASM is a two pass assembler.  The first pass creates the
  274.         symbol table and the second pass does the assembly.  The
  275.         assembler accepts as input an <filename>.ASM source file written
  276.         in ZILOG assembly language and outputs both an Intel formatted
  277.         <filename.HEX> object file and an assembly listing to the
  278.         printer in real time, either of which may be disabled.  This
  279.         assembler does not create any intermediate files, <filename.PRN>
  280.         or <filename.SYM> files.
  281.  
  282.         The symbol table is created starting at 22A2H and may be expanded
  283.         up to CCP base without harm.  There is no trap for symbol tables
  284.         that overwrite CCP.  The maximum number of symbolic entries is
  285.         dependent on memory available with the system configuration and
  286.         the aggregate length of each symbol plus 4 bytes per symbol.
  287.  
  288.         All program I/O is done through FDOS calls to 0005H.  All read,
  289.         write and working buffers, except the symbol table, are internal
  290.         to the program.  This assembler was written in 8080 assembly
  291.         language probably as a bootstrap to writing a more effecient and
  292.         fully featured Z80 assembler.
  293.  
  294.         INVOKING Z80ASM:  The format is:
  295.  
  296.                   A>Z80ASM <filename>[.LH ]
  297.  
  298.         The assembler expects an input source file named <filename>.ASM.
  299.         The optional .LH extension is the (L)isting output and (H)ex file
  300.         output defeat option mechanism.  The true state of the option
  301.         (defeated) is invoked by typing 'N' in the appropriate location,
  302.         any other character enables the function.  Without the extension
  303.         both Listing output and Hex file output functions are enabled.
  304.         When the listing function is disabled, only assembly line errors
  305.         will be listed.  For example:
  306.  
  307.              <filename>.N     will disable the listing function but
  308.                                create a <filename>.HEX file as output.
  309.              <filename>.xN    will disable the .HEX file output but
  310.                                a listing is printed.  Where x is any
  311.                                permissible CP/M .typ char except a space
  312.  
  313.         SOURCE CODE FILE LIMITATIONS:
  314.  
  315.         Source code files may be of any length acceptable to CP/M,
  316.         however, there is a practical limit to the size of the symbol
  317.         table which is not written to a file but held in memory between
  318.         22A2H and CCP base.
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325.                                         1
  326.  
  327.  
  328.  
  329.  
  330.  
  331.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  332.  
  333.  
  334.         SOURCE CODE LINES:
  335.  
  336.         Source code lines may not exceed 80 characters including CR & LF
  337.         and must be terminated by LF (0AH).  Most routines test for CR to
  338.         exit.
  339.  
  340.         LOWER/UPPER CASE TRANSLATION:
  341.  
  342.         Presently, ALL lower case ascii characters are translated to
  343.         upper case, including strings enclosed by single quote marks.
  344.  
  345.         OPCODES AND OPERANDS:
  346.  
  347.         Opcodes may NOT start in column 1.  Opcodes and their operands
  348.         follow the rules established by Zilog in the Z80-Assembly
  349.         Language Programming Manual.
  350.  
  351.         RESERVED WORDS:
  352.  
  353.         Certain symbolic names are reserved as key words in the operand
  354.         fields.  They are:
  355.  
  356.         Register names:   A, B, C, D, E, H, L, AF, BC, DE, HL, AF'
  357.         Flag Conditions:  C, NC, Z, NZ, M, P, PO, PE
  358.  
  359.         Using a reserved word as a smybolic reference in the operand
  360.         field will give erroneous operand values.
  361.  
  362.         EXPRESSIONS:
  363.  
  364.         Expressions are operand entries and may be unary (single term) or
  365.         binary.  Elements of the expression are connected by the
  366.         arithmetic operators + (addition), - (subtraction) , and  *
  367.         (multiplication).
  368.  
  369.         Expression elements may be numbers which begin with a numeric
  370.         digit, symbolic references which begin with an alpha charater
  371.         (LABELS: and EQUates), $ symbol for the current value of the
  372.         reference counter and a single ascii character enclosed in single
  373.         quote marks which equates to a hexadecimal number.  Expressions
  374.         are terminated by any other characters, usually a space or comma.
  375.  
  376.         Expressions are evaluated from left to right, parentheses are not
  377.         permitted.  Expression evaluation results are limited to 2 bytes
  378.         (16 bits) in length with a maximum unsigned value of 65,535.
  379.  
  380.         NUMBERS:
  381.  
  382.         Numbers MUST begin with a numeric digit, leading zeroes will
  383.         suffice.  Numbers may be written in hexadecimal, decimal or
  384.         binary bases.  Hexadecimal numbers must be followed immediately
  385.         by the 'H' radix indicator, Binary numbers must be followed
  386.         immediately by the 'B' radix indicator.  Decimal numbers are not
  387.         followed by a radix letter indicator.
  388.  
  389.  
  390.  
  391.                                         2
  392.  
  393.  
  394.  
  395.  
  396.  
  397.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  398.  
  399.  
  400.         LABELS:
  401.  
  402.         Labels MUST start in column 1.  A label is a string of one or
  403.         more characters and must begin with an alpha character.  Valid
  404.         characters are A-Z, 0-9, $, period (.) and trailing colon (:).
  405.         Labels are terminated by any other character, usually a space or
  406.         comma.  Labels may be up to 11 characters in length (excluding
  407.         colons), all characters are unique.  Trailing colons are optional
  408.         and ignored by the assembler (ie., LABELS: = LABELS ).  Labels
  409.         may not be a reserved word.  Examples of valid labels are:
  410.  
  411.              LABEL     LABEL:    LABEL$    LONG.LABEL     LONGERLABEL
  412.  
  413.              WARNING: at present the reserved word trap does not work.
  414.              An opcode or reserved word in an expression or starting in
  415.              column 1 will cause your program to crash!  Also, the last
  416.              label stored in the symbol table will give erroneous values,
  417.              therefore, DO NOT reference the last label in the body of a
  418.              program.
  419.  
  420.  
  421.         PSEUDO-OPS:
  422.  
  423.         Pseudo-ops are instructions to the assembler and as such do not
  424.         generate object code.  Psuedo-ops are summerized below:
  425.  
  426.              ORG  e         Sets the reference counter to the value of
  427.                             expression e.
  428.  
  429.              EQU  e         Sets the value of a label to e.  Can occur
  430.                             only once per label.
  431.  
  432.              END   e        Signifies the end of source code -- all code
  433.                             after END is ignored.  Expression e evaluates
  434.                             to the program starting address for .HEX
  435.                             files loaded with LOAD (e = 100H is normal)
  436.  
  437.              EJECT          Forces a new page in listing.
  438.  
  439.              DEFS e         Reserves e bytes of memory.  Advances
  440.                             reference counter RC = RC + e.
  441.  
  442.              DEFB e         Defines one byte of memory to equal value e.
  443.  
  444.              DEFB '$tring'  Defines n bytes of memory as the ascii
  445.                             equivalent of the characters in the $tring
  446.                             enclosed by single quote marks. n
  447.                             equals the number of chars in the string.
  448.  
  449.              DEFW e         Defines two bytes of memory to be equal to
  450.                             the value of e.  e is stored in memory as low
  451.                             byte -- high byte, ie., CRLF  EQU   0D0AH...
  452.                             DEFW   CRLF... produces 0A, 0D in consecutive
  453.                             bytes of memory.
  454.  
  455.  
  456.  
  457.                                         3
  458.  
  459.  
  460.  
  461.  
  462.  
  463.          Z80ASM-DD 2.4 --->  FIXES TO Z80ASM-2.0            DD 9/12/87
  464.  
  465.  
  466.              IBM  e         Defines n bytes of memory as the hex equiva-
  467.                             lent of the ascii elements in the expression
  468.                             e where n is the number of elements and takes
  469.                             the form:
  470.  
  471.                                  IBM     c1,c2,'$tring',c3,...,cn
  472.  
  473.                             where values of c are the hex representation
  474.                             of ascii characters without base indicator
  475.                             (H) and elements are seperated by a comma.
  476.                             Strings are enclosed by single quotes and
  477.                             each character of a string is considred an
  478.                             element. Single quotes may be included by
  479.                             defining cx = 27 (H).  Symbolic equivalents
  480.                             are not allowed (ie., CR  EQU  0DH...IBM
  481.                             CR,..).  e is terminated by a CR.  Usage
  482.                             example, a $ terminated message:
  483.  
  484.                                  IBM       0D,0A,'MESSAGE',0D,0A,'$'
  485.  
  486.                   where e is an expression as defined above.
  487.  
  488.         MACRO, CONDitional, EXTERNAL and GLOBAL pseudo-ops and LOGICAL
  489.         operators are not implemented in this version of Z80ASM.
  490.  
  491.         COMMENT LINES:
  492.  
  493.         Comment lines are defined as any string following a semicolon (;)
  494.         in a line.  Comments may start in any column and are ignored by
  495.         the assembler.
  496.  
  497.         ASSEMBLER ERROR MESSAGES:
  498.  
  499.         Assembly error messages are one character codes which are placed
  500.         in the first column of the line containing the error in the
  501.         output listing.
  502.  
  503.         L    Label length error -- label > 11 characters long
  504.  
  505.         M    Label is either a reserved word or previously defined (not
  506.                implemented in version 2.4)
  507.  
  508.         O    "Overflow" -- indicates that the op code as spelled was
  509.                not found in reference table.
  510.  
  511.         U    Undefined label in the operand field
  512.  
  513.         $    Displacement range error -- range = -127 < expression <+130
  514.  
  515.                                                                   DD
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.                                         4
  524.  
  525.  
  526.  
  527.  
  528.  
  529.