.Z80 ; struct.mac v1.10 1/20/88 .XLIST ; this macro library implements some basic structured programming ; constructs for the Microsoft M80 assembler. it was tested using ; version 3.44 (dated 09-DEC-81 in its output listings). ; some initialization @iflvl aset 0 @brlvl aset 0 @caslvl aset 0 ; "inner" macro definitions ; macro for versatile symbol value assignment @getput macro symbol,val symbol aset val endm ; push a value onto a virtual assembler stack. @push macro stk,val .ifndf stk,0 if stk eq 0ffffh +++++++ @push_overflow stk else stk aset stk+1 @getput stk%stk,val endif endm ; pop a value from a virtual assembler stack. @pop macro stk,symbol .ifndf stk,0 if stk eq 0 +++++++ @pop_underflow stk else @getput symbol,stk%stk stk aset stk-1 endif endm ; perform a jump to a generated label @jump macro a1,a2 if nul a2 jp a1 else jp a1,a2 endif endm ; perform a jump to a label with inverse condition @ijump macro a1,a2,a3 if nul a2 jp a1&a3 exitm endif ifidn , jp z,a2&a3 exitm endif ifidn , jp nz,a2&a3 exitm endif ifidn , jp c,a2&a3 exitm endif ifidn , jp nc,a2&a3 exitm endif ifidn , jp pe,a2&a3 exitm endif ifidn , jp po,a2&a3 exitm endif ifidn ,

jp m,a2&a3 exitm endif ifidn , jp p,a2&a3 endif endm ; conditional label generator @lbl macro a1,a2,a3 if nul a2 a1&a3: else if1 ifndef a1 a1&a3: else a2&a3: endif else ifndef a2 a1&a3: else a2&a3: endif endif endif endm ; "in-line" macro definitions ; conditional symbol definition macro .ifndf macro var,val ifndef var var aset val endif endm ; generate code for beginning of ".if" statement. .if macro cond if nul cond +++++++ if_condition_not_specified else @push @if,@iflvl @ijump cond,@ei1%@iflvl @iflvl aset @iflvl+1 endif endm ; generate code for ".else" clause of ".if". .else macro @pop @if,@gp @push @if,@gp @ijump @ei2%@gp @lbl @ei1%@gp endm ; generate code for ".endif" clause of ".if". .endif macro @pop @if,@gp @lbl @ei1%@gp,@ei2%@gp endm ; generate code to begin ".do" while statement .do macro @push @br,@brlvl @lbl @ibr%@brlvl @brlvl aset @brlvl+1 endm ; generate beginning of body of ".while" loop .while macro cond if nul cond +++++++ while_condition_not_specified else @pop @br,@gp @push @br,@gp @ijump cond,@ebr%@gp endif endm ; generate code for ".until" termination of do loop .until macro cond if nul cond +++++++ until_condition_not_specified else @pop @br,@gp @ijump cond,@ibr%@gp @lbl @ebr%@gp endif endm ; generate code for ".enddo" termination of do loop .enddo macro @pop @br,@gp @ijump @ibr%@gp @lbl @ebr%@gp endm ; generate code to start a ".switch" construct .switch macro @push @br,@brlvl @brlvl aset @brlvl+1 @push @case,@caslvl @caslvl aset @caslvl+1 endm ; generate code to start each ".case" .case macro @pop @br,@gp @push @br,@gp @lbl @cas%@gp,,%@caslvl @caslvl aset @caslvl+1 endm ; generate code for ".cond" conditional branch for ".case" .cond macro cond if nul cond +++++++ cond_condition_not_specified else @pop @br,@gp @push @br,@gp @ijump cond,@cas%@gp,%@caslvl endif endm ; generate code for ".otherwise" .otherwise macro .case endm ; generate code for ".endsw" .endsw macro @pop @br,@gp @lbl @ebr%@gp @pop @case,@caslvl endm ; generate code for ".break" termination .break macro cond @pop @br,@gp @push @br,@gp if nul cond @jump @ebr%@gp else @jump cond,@ebr%@gp endif endm .LIST