home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / m80str11.lbr / STRUCT.DZC / STRUCT.DOC
Text File  |  1988-02-16  |  8KB  |  199 lines

  1.  
  2. Z80 structured programming macro library.
  3.  
  4. -----------------------------------------------------------------------------
  5.     
  6.     Version 1.10
  7.  
  8.     Fixed a bug in the expansion of ".case" and ".cond" macros that
  9.     cropped up when ".switch" constructs were nested inside each other.
  10.  
  11. -----------------------------------------------------------------------------
  12.  
  13. This is a macro library that implements a small number of very open ended
  14. structured programming constructs for the Microsoft M80 macro assembler. The
  15. code has been tested using version 3.44 (which is dated 09-DEC-81 in the page
  16. headers of its *.PRN output listings.) Since I have access to no other
  17. assemblers, I was unable to test it for any others, nor for other releases of
  18. M80. I am fairly confident, however that it should run on M80 generally and
  19. perhaps less confident that it could easily be ported to other macro assemblers.
  20.  
  21. The macros were written using Zilog Z80 mnemonics. All that is required to
  22. convert it to Intel 8080 mnemonics id to remove the ".Z80" switch at the top of
  23. the file (or replace it with ".8080") and to replace all occurrences of the "jp"
  24. instruction (used in macros "@jump" and "@ijump" only) with "jmp". That's the
  25. only machine executable instruction used in the file, the rest of it consisting
  26. of assembler symbol manipulations to keep track of what's next and to generate
  27. labels in appropriate locations.
  28.  
  29. I did originally write the macros used for jumping to use relative jumps
  30. wherever possible for the smaller and quicker code they produce, but
  31. unfortunately this only works if the label has been defined already, and there
  32. is no way to get around the problem that I can see (at least not a worthwhile
  33. one) so the generic jump instruction was used throughout. The jump instructions
  34. themselves could be generated more quickly using "db" assembler directives,
  35. but the string comparison method used generates more readable assembler
  36. listings, which can be useful for debugging.
  37.  
  38. The possible combinations of these constructs are virtually endless. The macros
  39. were designed with the intention of leaving as much versatility as possible
  40. in their structure. There is no reason, for instance, that a single .do loop
  41. couldn't have both a .while condition clause at the top and a .until condition
  42. clause at the top, although I wouldn't recommend doing so. By the same token,
  43. that same .do loop could be set up without any condition clause (in which case
  44. you better be doing SOMETHING to leave it, because that is an infinite loop
  45. by design...)
  46.  
  47. While I have not had much opportunity to use these macros extensively yet,
  48. I do use a set of such macros in a mainframe assembler environment. They have
  49. the ability to relieve the programmer of the drudgery of working out the exact
  50. details of many nested loops, multi-condition routines and the invention of
  51. various and sundry labels. (Face it - making up lots of meaningless and similar
  52. sounding labels is a pain in the ...)
  53.  
  54. All constructs may be nested within any other constructs to what is, for
  55. practical purposes an infinite degree. The only condition is the same as in any
  56. language that implements them: their individual elements must be kept together
  57. in the sense that you cannot begin a .do loop in an .if clause and end it
  58. outside.
  59.  
  60. Macros included:
  61.  
  62.         @getput     macros starting with "@" are intended for use
  63.         @push       internally to other macros only. This doesn't
  64.         @pop        preclude using them otherwise, however.
  65.         @jump
  66.         @ijump
  67.         @lbl
  68.  
  69.         .ifndf      semi-internal macro - not really necessary, but nice.
  70.  
  71.         .if         if ... else ... endif construct
  72.         .else
  73.         .endif
  74.  
  75.         .break      applies to ths constructs below - terminates 
  76.                         .do and .switch
  77.  
  78.         .do         loop construct
  79.         .while
  80.         .until
  81.         .enddo
  82.  
  83.         .switch     case select construct
  84.         .case
  85.         .cond
  86.         .endsw
  87.  
  88.  
  89.  
  90.  
  91. Usage:
  92.  
  93. In the following descriptions, the <condition> can be one of:
  94.         z   nz  c   nc  po  pe  p   m
  95. which are the standard Z80 branch instruction conditions.
  96.  
  97.  
  98. The if...then...else construct requires that you precede it with some code that
  99. sets the flags. Once the flags are set and you wish to base conditional
  100. execution on them, you can code:
  101.  
  102.         --- code that sets flags ---
  103.         .if     <condition>
  104.                 --- code to execute if <condition> true ---
  105.         .else
  106.                 --- code to execute if <condition> false  ---
  107.         .endif
  108.  
  109. The ".else" clause is completely optional.
  110.  
  111.  
  112. The ".break" macro applies to any ".do" loop and/or any ".switch" case. It can
  113. be specified with a <condition> or without. More on this one later.
  114.  
  115.  
  116. The ".do" constructs all implement loops, but quite a variety are possible.
  117. A simple:
  118.  
  119.         .do
  120.                 --- body of loop ---
  121.         .enddo
  122.  
  123. provides you an inifinite loop. You can include a ".break" (with or witout) its
  124. optional <condition> to exit the body of the loop.
  125.  
  126. The ".while" is used like so:
  127.  
  128.         .do
  129.                 --- code to set the flags ---
  130.         .while  <condition>
  131.                 --- body of loop ---
  132.         .enddo
  133.  
  134. The ".until" is used like:
  135.  
  136.         .do
  137.                 --- body of loop ---
  138.         .until  <condition>
  139.  
  140. Note that the ".until" REPLACES the ".enddo".
  141.  
  142. Either of the above can have a ".break" for early termination. While I haven't
  143. actually tried it, I see no reason why you couldn't create a ".do" loop that
  144. contained BOTH an ".until" AND a ".while".
  145.  
  146.  
  147. The ".switch" construct has the basic structure:
  148.  
  149.         .switch
  150.             .case
  151.                 --- code to set the flags ---
  152.                 .cond   <condition>
  153.                     --- body of case ---
  154.                     .break
  155.             .case
  156.                 --- code to set the flags ---
  157.                 .cond   <condition>
  158.                     --- body of case ---
  159.                     .break
  160.             .case
  161.                 --- code to set the flags ---
  162.                 .cond   <condition>
  163.                     --- body of case ---
  164.                     .break
  165.             .otherwise
  166.                 --- code to execute otherwise ---
  167.             .endsw
  168.  
  169. Note the ".break" statements at the end of each case/cond. I swiped the basic
  170. layout of the switch statement from the C language, and decided to include this.
  171. The case/cond pairs simply provide a test and an entry point to the code. Thus
  172. if you left the ".break" statements out, control would enter the code at the
  173. first test that was satisfied, then continue falling thru, skipping subsequent
  174. tests that were not satisfied, until it fell out the ".endsw" statement. The
  175. ".break" statements will cause the control to be passed out of the switch/endsw
  176. range. While this requires some extra typing, it adds a variety of flexible
  177. possibilities to the usage of ".switch". The .break statements could have
  178. conditions associated with them, in which you case you can construct .switch
  179. statements that select and execute a single .case under some conditions, and act
  180. as multiple entry point routines with some or complete fall through in other
  181. situations. Pretty weird, but interesting...
  182.  
  183. Files included:
  184.  
  185. STRUCT.FOR      Short statement of purpose
  186. STRUCT.DOC      This doc file.
  187. STRUCT.MAC      Full source to the macros.
  188. STRUCT.LIB      Same as above, but with comments and extra spaces
  189.                 stripped out for quicker assembly and less wasted TPA.
  190.                 Use this as your "INCLUDE" file.
  191.  
  192. Have fun.                   Al Grabauskas
  193.  
  194. I can be contacted at the LILLIPUTE Z-NODE in Chicago if you have any
  195. questions or comments.
  196.                         (312) 649-1730
  197.                         (312) 664-1730
  198.  
  199.