.xlist
;
;  COPYRIGHT @ 1982
;	Jim Holtman
;
;  Structured Control MACROS for the Assembler
;
.$on=1
.cnt=1
.lvl=0
.$top=1
xopsyn	macro	op1,op2
@&op1	equ	op2
@&op2	equ	op1
	endm

	xopsyn	jbe,ja
	xopsyn	jae,jb
	xopsyn	jc,jnc
	xopsyn	je,jne
	xopsyn	jz,jnz
	xopsyn	jg,jle
	xopsyn	jge,jl
	xopsyn	jno,jo
	xopsyn	jpo,jpe
	xopsyn	jns,js
	purge	xopsyn
; create label
.$lbl	macro	id,num
					id&num:
	endm

.popdo	macro
	if	.$top lt 1
	  %out stack overflow
	else
	  .$top = .$top-1
	  .$get %.$top,.dold
	endif
	endm

.$get	macro	entry,value
value = .&entry
	endm

.$put	macro	entry,value
.&entry = value
	endm

.pushdo macro	x
	ifnb	<x>
	  x = .cnt
	  .cnt = .cnt+1
	endif
	.$put	%.$top,.dold
	.$top = .$top+1
	endm

.$br	macro	type,id,label,long
	local	lab
	ifnb	<long>
					j&type	lab
					jmp	id&label
					lab:
	else
					@j&type  id&label
	endif
	endm


.doo	macro	cond,long
	.pushdo .dold
	.lvl = .lvl+1
	.$br	cond,d@,%.dold,long
	endm

.endif	macro
	.popdo
	.$lbl	d@,%.dold
	.lvl = .lvl-1
	endm

.if	macro	arg1,cond,arg2,long
	ifb	<arg2>
	  .doo	arg1,cond
	else
					cmp	arg1,arg2
	  .doo	cond,long
	endif
	endm

.ifs	macro	p1,p2,long
					test	p1,p2
	.if	nz,long
	endm

.ifc	macro	p1,p2,long
					test	p1,p2
	.if	z,long
	endm

.else	macro	long
	.doif = .cnt
	.cnt = .cnt+1
	ifnb	<long>
	  .$jmp d@,%.doif
	else
	  .$jmp <short d@>,%.doif
	endif
	.endif
	.lvl = .lvl+1
	.dold = .doif
	.pushdo
	endm

.$jmp	macro	id,num
					jmp	id&num
	endm

.dowhl	macro	p1,cond,p2,long
	ifnb	<p2>
	  .$do	long
	  .if	<p1>,cond,<p2>,long
	else
	  .$do	cond
	  .if	p1,cond
	endif
	endm

.enddo	macro
	.popdo
	.doif = .dold
	.popdo
	.xxtemp = .dold and 8000h
	if .xxtemp eq 0
	  .$jmp <short d@>,%.dold
	else
	  .dold = .dold and 7fffh
	  .$jmp d@,%.dold
	endif
	.lvl = .lvl-1
	.$lbl d@,%.doif
	endm

check$	macro
	if .$top ne 1
	  %out stack not empty
	endif
	if .lvl ne 0
	  %out nesting level mismatch
	endif
	endm

.$do	macro	long
	.pushdo .dold
	ifnb	<long>
	  .xxtemp = .$top-1
	  .$get %.xxtemp,.dold
	  .$put %.xxtemp,<.dold or 8000h>
	endif
	.xxtemp = .dold and 7fffh
	.$lbl d@,%.xxtemp
	endm

.repeat macro
	.$do
	.lvl = .lvl+1
	endm

.until	macro	p1,cond,p2,long
	ifidn	<p1>,<loop>
	  .popdo
	  .$loop loop&cond,d@,%.dold
	else
	  ifnb <p2>
					cmp p1,p2
	    .popdo
	    .$br cond,d@,%.dold,long
	  else
	    .popdo
	    .$br p1,d@,%.dold,cond
	  endif
	endif
	.lvl = .lvl-1
	endm

.$loop	macro	type,id,num
					type	id&num
	endm

@pop	macro	parm
	irp	@@pop,<parm>
	ifnb	<@@pop>
	pop	@@pop
	endif
	endm
	endm

@save	macro	p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12
	irp	@@save,<p1,p2,p3,p4,p5,p6,p7,p8,p9,p10,p11,p12>
	ifnb	<@@save>
	push	@@save
	endif
	endm
@restore macro
	@pop	<p12,p11,p10,p9,p8,p7,p6,p5,p4,p3,p2,p1>
	endm
	endm
.list
