home *** CD-ROM | disk | FTP | other *** search
-
- Z80 structured programming macro library.
-
- -----------------------------------------------------------------------------
-
- Version 1.10
-
- Fixed a bug in the expansion of ".case" and ".cond" macros that
- cropped up when ".switch" constructs were nested inside each other.
-
- -----------------------------------------------------------------------------
-
- This is a macro library that implements a small number of very open ended
- structured programming constructs for the Microsoft M80 macro assembler. The
- code has been tested using version 3.44 (which is dated 09-DEC-81 in the page
- headers of its *.PRN output listings.) Since I have access to no other
- assemblers, I was unable to test it for any others, nor for other releases of
- M80. I am fairly confident, however that it should run on M80 generally and
- perhaps less confident that it could easily be ported to other macro assemblers.
-
- The macros were written using Zilog Z80 mnemonics. All that is required to
- convert it to Intel 8080 mnemonics id to remove the ".Z80" switch at the top of
- the file (or replace it with ".8080") and to replace all occurrences of the "jp"
- instruction (used in macros "@jump" and "@ijump" only) with "jmp". That's the
- only machine executable instruction used in the file, the rest of it consisting
- of assembler symbol manipulations to keep track of what's next and to generate
- labels in appropriate locations.
-
- I did originally write the macros used for jumping to use relative jumps
- wherever possible for the smaller and quicker code they produce, but
- unfortunately this only works if the label has been defined already, and there
- is no way to get around the problem that I can see (at least not a worthwhile
- one) so the generic jump instruction was used throughout. The jump instructions
- themselves could be generated more quickly using "db" assembler directives,
- but the string comparison method used generates more readable assembler
- listings, which can be useful for debugging.
-
- The possible combinations of these constructs are virtually endless. The macros
- were designed with the intention of leaving as much versatility as possible
- in their structure. There is no reason, for instance, that a single .do loop
- couldn't have both a .while condition clause at the top and a .until condition
- clause at the top, although I wouldn't recommend doing so. By the same token,
- that same .do loop could be set up without any condition clause (in which case
- you better be doing SOMETHING to leave it, because that is an infinite loop
- by design...)
-
- While I have not had much opportunity to use these macros extensively yet,
- I do use a set of such macros in a mainframe assembler environment. They have
- the ability to relieve the programmer of the drudgery of working out the exact
- details of many nested loops, multi-condition routines and the invention of
- various and sundry labels. (Face it - making up lots of meaningless and similar
- sounding labels is a pain in the ...)
-
- All constructs may be nested within any other constructs to what is, for
- practical purposes an infinite degree. The only condition is the same as in any
- language that implements them: their individual elements must be kept together
- in the sense that you cannot begin a .do loop in an .if clause and end it
- outside.
-
- Macros included:
-
- @getput macros starting with "@" are intended for use
- @push internally to other macros only. This doesn't
- @pop preclude using them otherwise, however.
- @jump
- @ijump
- @lbl
-
- .ifndf semi-internal macro - not really necessary, but nice.
-
- .if if ... else ... endif construct
- .else
- .endif
-
- .break applies to ths constructs below - terminates
- .do and .switch
-
- .do loop construct
- .while
- .until
- .enddo
-
- .switch case select construct
- .case
- .cond
- .endsw
-
-
-
-
- Usage:
-
- In the following descriptions, the <condition> can be one of:
- z nz c nc po pe p m
- which are the standard Z80 branch instruction conditions.
-
-
- The if...then...else construct requires that you precede it with some code that
- sets the flags. Once the flags are set and you wish to base conditional
- execution on them, you can code:
-
- --- code that sets flags ---
- .if <condition>
- --- code to execute if <condition> true ---
- .else
- --- code to execute if <condition> false ---
- .endif
-
- The ".else" clause is completely optional.
-
-
- The ".break" macro applies to any ".do" loop and/or any ".switch" case. It can
- be specified with a <condition> or without. More on this one later.
-
-
- The ".do" constructs all implement loops, but quite a variety are possible.
- A simple:
-
- .do
- --- body of loop ---
- .enddo
-
- provides you an inifinite loop. You can include a ".break" (with or witout) its
- optional <condition> to exit the body of the loop.
-
- The ".while" is used like so:
-
- .do
- --- code to set the flags ---
- .while <condition>
- --- body of loop ---
- .enddo
-
- The ".until" is used like:
-
- .do
- --- body of loop ---
- .until <condition>
-
- Note that the ".until" REPLACES the ".enddo".
-
- Either of the above can have a ".break" for early termination. While I haven't
- actually tried it, I see no reason why you couldn't create a ".do" loop that
- contained BOTH an ".until" AND a ".while".
-
-
- The ".switch" construct has the basic structure:
-
- .switch
- .case
- --- code to set the flags ---
- .cond <condition>
- --- body of case ---
- .break
- .case
- --- code to set the flags ---
- .cond <condition>
- --- body of case ---
- .break
- .case
- --- code to set the flags ---
- .cond <condition>
- --- body of case ---
- .break
- .otherwise
- --- code to execute otherwise ---
- .endsw
-
- Note the ".break" statements at the end of each case/cond. I swiped the basic
- layout of the switch statement from the C language, and decided to include this.
- The case/cond pairs simply provide a test and an entry point to the code. Thus
- if you left the ".break" statements out, control would enter the code at the
- first test that was satisfied, then continue falling thru, skipping subsequent
- tests that were not satisfied, until it fell out the ".endsw" statement. The
- ".break" statements will cause the control to be passed out of the switch/endsw
- range. While this requires some extra typing, it adds a variety of flexible
- possibilities to the usage of ".switch". The .break statements could have
- conditions associated with them, in which you case you can construct .switch
- statements that select and execute a single .case under some conditions, and act
- as multiple entry point routines with some or complete fall through in other
- situations. Pretty weird, but interesting...
-
- Files included:
-
- STRUCT.FOR Short statement of purpose
- STRUCT.DOC This doc file.
- STRUCT.MAC Full source to the macros.
- STRUCT.LIB Same as above, but with comments and extra spaces
- stripped out for quicker assembly and less wasted TPA.
- Use this as your "INCLUDE" file.
-
- Have fun. Al Grabauskas
-
- I can be contacted at the LILLIPUTE Z-NODE in Chicago if you have any
- questions or comments.
- (312) 649-1730
- (312) 664-1730
-