Metropoli BBS
VIEWER: sit.inc MODE: TEXT (ASCII)
	.xlist

;STANDARD macros for use in 8086 assembly work, including

; 1) standard definitions of CR, LF, TAB, etc.

; 2) standard BIOS and DOS interrupt numbers

; 3) standard "extended" opcodes (far call, return, bit set/clear ops, etc.)

; 4) structured _IF/_ELSEIF/_ELSE/_ENDIF and _WHILE/_BREAK/_AGAIN/_UNTIL

;=============================================

; 1) standard definitions of CR, LF, TAB, ESCAPE etc.
cr	equ	0dh
lf	equ	0ah
tab	equ	09h
escape	equ	1bh
eot	equ	4
ack	equ	6
nak	equ	21
bs	equ	08h

;=============================================

; 2) standard BIOS and DOS interrupt numbers

;call to DOS function
dos	macro
	int	21h
	endm

;BIOS video display services
video	macro
	int	10h
	endm

;BIOS serial-port services
serial	macro
	int	14h
	endm

;BIOS device control services
device	macro
	int	15h
	endm

;BIOS "a key has been pressed" service
keypress macro
	int	9h
	endm

;BIOS "get a keystroke" services
keyboard  macro
	int	16h
	endm

;BIOS printer services
printer macro
	int	17h
	endm

;BIOS once-a-tick user services
usertick macro
	int	1ch
	endm

;"DOS is doing an I/O function, may be interrupted for DOS calls > 0Ch" ticker
idler	macro
	int	28h
	endm

;=============================================

; 3) standard "extended" opcodes (far call, return, bit set/clear ops, etc.)

;"far" call, jump
jmpf	macro
	db	0eah
	endm

callf	macro
	db	09ah
	endm

setbits macro	target,bits
	or	target,bits
	endm

clrbits macro	target,bits
	and	target,not(bits)
	endm

tstbits macro	target,bits
	test	target,bits
	endm

zero	macro	register
	xor	register,register
	endm

;=============================================

; 4) structured _IF/_ELSEIF/_ELSE/_ENDIF and _WHILE/_BREAK/_AGAIN/_UNTIL

;"negated no condition" jump
jn	macro	target
	jmp	short target
	endm

;"no condition" jump
j	macro	target
	jmp	short target
	endm

;"Double-negative" conditional jumps
jnpo	macro	target
	jpe	target
	endm

jnpe	macro	target
	jpo	target
	endm

jnna	macro	target
	ja	target
	endm

jnnae	macro	target
	jae	 target
	endm

jnnb	macro	target
	jb	target
	endm

jnnbe	macro	target
	jbe	 target
	endm

jnnc	macro	target
	jc	target
	endm

jnne	macro	target
	je	target
	endm

jnng	macro	target
	jg	target
	endm

jnnge	macro	target
	jge	 target
	endm

jnnl	macro	target
	jl	target
	endm

jnnle	macro	target
	jle	 target
	endm

jnno	macro	target
	jo	target
	endm

jnnp	macro	target
	jp	target
	endm

jnns	macro	target
	js	target
	endm

jnnz	macro	target
	jz	target
	endm

jnncxz	macro	target
	jcxz	target
	endm

; third-level macros to substitute jumps and jump targets
___jj	macro	cnd,target,depth
	j&cnd	target&depth
	endm

___ll	macro	cnd,target,depth
	loop&cnd   target&depth
	endm

___tt	macro	target,depth
target&depth:
	endm

; second-level macros to substitute jumps and jump targets

___jn	macro	cnd,target,type,depth
	___jj	n&cnd,target,%&type&depth
	endm

___j	macro	cnd,target,type,depth
	___jj	cnd,target,%&type&depth
	endm

___l	macro	cnd,target,type,depth
	___ll	cnd,target,%&type&depth
	endm

___t	macro	target,type,depth
	___tt	target,%&type&depth
	endm

___makesym	macro	name,num,val
name&num	=	val
	endm

;test to insure you're nesting structures correctly

___test macro	depth,kind
	if	___depth EQ 0
	.ERR
	%OUT	>>> invalid nesting
	exitm
	endif
	if	kind NE ___type_&depth
	.ERR
	%OUT	>>> invalid nesting
	exitm
	endif
	endm

;find the innermost enclosing loop, if any
___findloopdepth macro trydepth
___loopdepth  = trydepth
	if	trydepth LE 0
	.ERR
	%OUT	>>> BREAK/AGAIN not within a loop
	exitm
	endif
	if	___type_&trydepth NE 2
___loopdepth = ___loopdepth - 1
	___findloopdepth %___loopdepth
	endif
	endm

;structured forms

_if	macro	op,cnd
___depth	=	___depth+1
___targetcnt	=	___targetcnt+1
	___makesym	___type_,%___depth,1
	___makesym	___end_,%___depth,___targetcnt
	___makesym	___skip_,%___depth,___targetcnt
	op
	___jn	cnd,_s_,___skip_,%___depth
	endm

_elseif macro	op,cnd
	___test %___depth,1
	___j	,_e_,___end_,%___depth
	___t	_s_,___skip_,%___depth
___targetcnt	=	___targetcnt+1
	___makesym	___skip_,%___depth,___targetcnt
	op
	___jn	cnd,_s_,___skip_,%___depth
	endm

_else	macro
	___test %___depth,1
	___j	,_e_,___end_,%___depth
	___t	_s_,___skip_,%___depth
___targetcnt	=	___targetcnt+1
	___makesym	___skip_,%___depth,___targetcnt
	endm

_endif	macro
	___test %___depth,1
	___t	_s_,___skip_,%___depth
	___t	_e_,___end_,%___depth
___depth	=	___depth - 1
	endm

_while	macro	op,cnd
___depth	=	___depth+1
___targetcnt	=	___targetcnt+1
	___makesym	___type_,%___depth,2
	___makesym	___top_,%___depth,___targetcnt
	___makesym	___bottom_,%___depth,___targetcnt
	___t	_w_,___top_,%___depth
	op
	ifnb	<cnd>
	___jn	cnd,_u_,___bottom_,%___depth
	endif
	endm

_break	macro	op,cnd
	___findloopdepth  %___depth
	op
	___j	cnd,_u_,___bottom_,%___loopdepth
	endm

_again	macro	op,cnd
	___findloopdepth  %___depth
	op
	___j	cnd,_w_,___top_,%___loopdepth
	endm

_until	macro	op,cnd
	___test %___depth,2
	op
	___jn	cnd,_w_,___top_,%___depth
	___t	_u_,___bottom_,%___depth
___depth	=	___depth - 1
	endm

_againcx macro	 cnd
	___test %___depth,2
	___l	cnd,_w_,___top_,%___depth
	endm

_nextcx macro	cnd
	___test %___depth,2
	___l	cnd,_w_,___top_,%___depth
	___t	_u_,___bottom_,%___depth
___depth	=	___depth - 1
	endm

; Synonyms for easy use

_loop	macro
	_while
	endm

_lend	macro
	_until
	endm

_wend	macro
	_until
	endm

_repeat macro
	_while
	endm

_cntnu	macro	op,cnd
	_again	<op>,cnd
	endm

___depth	=	0	; start _if/_else nesting at level 0
___targetcnt	=	0	; start label counter at 0 (allows 65535 "local" labels)

	.list
[ RETURN TO DIRECTORY ]