;	asm(1.0) macro package - Various macros that may be
;	found useful.
;
;	This macro package has been written and placed in the
;	public domain by Douglas J Leavitt, 1986.  Feel free
;	to use this package in anyway whatsoever, hopefully
;	making millions of dollars in the process.
;
;	Global Macro Variables start with ___
;	___argchk is a local temp variable used by various macros
;	To pass extra params to the ARGCHK macro
;

;	ARGCHK	min_args,max_args,nargs
;
;	Check a macro invocation for the proper number of arguments

	ifnd	ASM_COMMON
	ASM_COMMON = 1
ARGCHK	macro
	ifne	narg-2
		___badarg=2	; args to ARGCHK are bad
		mexit
	endc
	___badarg=0		; Just the right amount
	iflt	___argchk-\\1
		___badarg=-1	; Not enough args
	endc
	ifgt	___argchk-\\2
		___badarg=1	; Too many args
	endc
	endm

	endc			; ASM_COMMON

;	SETFP	fp
;
;	Change the Default frame pointer variable (___deffp)
;
SETFP	macro
	___argchk=narg
	ARGCHK	1,1
	___deffp=\1
	endm

;	Initial setting
	SETFP	a6

;	CSAVE	local_size,[fp]
;
;	Generate a legal C function prolog (Without saving registers)
;	The default frame Pointer is:	___deffp   (normally a6)
;
CSAVE	macro
	___argchk=narg
	ARGCHK	1,2
	ifne	___badarg
		fail		; Generate a user warning
		mexit		; Incorrect arguments given
	endc
	iflt	\1
		fail
		mexit
	endc
	ifle	\1-32767
		ifeq	narg-1	; Use default fp (a6)
			link	___deffp,#\1
		endc
		ifeq	narg-2	; Use chosen fp
			link	\2,#\1
		endc
	endc
	ifgt	\1-32767
		ifeq	narg-1	; Use default fp (a6)
			link	___deffp,#0
			sub.l	#\1,sp
		endc
		ifeq	narg-2	; Use chosen fp
			link	\2,#0
			sub.l	#\1,sp
		endc
	endc
	endm

;	CRET	[fp]
;
;	generate C subroutine epilog (no register saving)
;
CRET	macro
	___argchk=narg
	ARGCHK	0,1
	ifeq	narg
		unlk	___deffp
	endc
	ifeq	narg-1
		unlk	\1
	endc
	rts
	endm

;	REGDIR	field1,field2,dir
;
;	sets ___movmask to either field1 or field2 depending on dir
;
REGDIR	macro
	___argchk=narg
	ARGCHK	3,3
	ifeq	\\3
		___movmask=\\1
	endc
	ifne	\\3
		___movmask=\\2
	endc
	endm

;	REGSET	reg_name,dir
;
;	sets ___movmask to be the value of the given regname
;	depending on the given direction.
;
REGSET	macro
	ifne	narg-2
		mexit
	endc
	ifc	\\1,"d0"
		REGDIR	0x0001,0x8000,\\2
	endc
	ifc	\\1,"d1"
		REGDIR	0x0002,0x4000,\\2
	endc
	ifc	\\1,"d2"
		REGDIR	0x0004,0x2000,\\2
	endc
	ifc	\\1,"d3"
		REGDIR	0x0008,0x1000,\\2
	endc
	ifc	\\1,"d4"
		REGDIR	0x0010,0x0800,\\2
	endc
	ifc	\\1,"d5"
		REGDIR	0x0020,0x0400,\\2
	endc
	ifc	\\1,"d6"
		REGDIR	0x0040,0x0200,\\2
	endc
	ifc	\\1,"d7"
		REGDIR	0x0080,0x0100,\\2
	endc
	ifc	\\1,"a0"
		REGDIR	0x0100,0x0080,\\2
	endc
	ifc	\\1,"a1"
		REGDIR	0x0200,0x0040,\\2
	endc
	ifc	\\1,"a2"
		REGDIR	0x0400,0x0020,\\2
	endc
	ifc	\\1,"a3"
		REGDIR	0x0800,0x0010,\\2
	endc
	ifc	\\1,"a4"
		REGDIR	0x1000,0x0008,\\2
	endc
	ifc	\\1,"a5"
		REGDIR	0x2000,0x0004,\\2
	endc
	ifc	\\1,"a6"
		REGDIR	0x4000,0x0002,\\2
	endc
	ifc	\\1,"a7"
		REGDIR	0x8000,0x0001,\\2
	endc
	endm

;	GENMOVEM	pred,dir,addr,reg1,reg2,....
;
;	pred is set if predecrement mode is to be used
;	dir  is 0 for movem to mem, 1 for movem to registers
;	addr is the addressing mode to use
;	reg1,reg2,... are the registers to save
;
GENMOVEM	macro
	___argchk=narg
	ARGCHK	4,16
	___movval=0
	REGSET	"\4",\1
	___movval=___movval!___movmask
	REGSET	"\5",\1
	___movval=___movval!___movmask
	REGSET	"\6",\1
	___movval=___movval!___movmask
	REGSET	"\7",\1
	___movval=___movval!___movmask
	REGSET	"\8",\1
	___movval=___movval!___movmask
	REGSET	"\9",\1
	___movval=___movval!___movmask
	REGSET	"\10",\1
	___movval=___movval!___movmask
	REGSET	"\11",\1
	___movval=___movval!___movmask
	REGSET	"\12",\1
	___movval=___movval!___movmask
	REGSET	"\13",\1
	___movval=___movval!___movmask
	REGSET	"\14",\1
	___movval=___movval!___movmask
	REGSET	"\15",\1
	___movval=___movval!___movmask
	REGSET	"\16",\1
	___movval=___movval!___movmask
	ifeq	\2
		movem.l	#___movval,\3
	endc
	ifne	\2
		movem.l	\3,#___movval
	endc
	endm

