IFNDEF	__SN8P2839_MACRO__
	__SN8P2839_MACRO__	EQU	1

;-------------------------------------------------------------------
; 2839 SPECIAL MACRO case
;-------------------------------------------------------------------

CJA	macro	v1, v2, adr
	IFIDNI	<v1>, <A>
		cmprs	a, v2
		b0bts1	FC
		jmp	$+4			//修改
	ELSEIFIDNI	<v2>, <A>
		cmprs	a, v1
		b0bts0	FC
		jmp	$+4			//修改
	ELSE
		ERROR	please use CJA_/CJB_ mem, mem, address
	ENDIF
	Jmp_Ret	<adr>
	endm

CJE	macro	v1, v2, adr
	IFIDNI	<v1>, <A>
		cmprs	a, v2
	ELSEIFIDNI	<v2>, <A>
		cmprs	a, v1
	ELSE
		ERROR	please use CJE_ mem, mem, address
	ENDIF
	jmp	$+4				//修改
	Jmp_Ret	<adr>
	endm

DJZ	macro	val, adr
	decms	val
	jmp		$+4			//修改
	Jmp_Ret	<adr>
	endm

IJZ	macro	val, adr
	incms	val
	jmp		$+4			//修改
	Jmp_Ret	<adr>
	endm

CJE_	macro	v1, v2, adr
	mov	a, v1
	cmprs	a, v2
	jmp	$+4				//修改
	Jmp_Ret	<adr>
	endm

;-------------------------------------------------------------------
; GENERAL MACRO case
;-------------------------------------------------------------------

;-------------------------------------------------------------------
; MACRO1.H
;-------------------------------------------------------------------

;-------------------------------------------------------------------
;
;	CLC	:	clear Carry Flag
;	STC	:	set Carry Flag
;	CLRWDT	:	reset Watch-Dog Count
;	NOT A	:	A = ~A
;	NEG A	:	A = -A
;
;	Note	:	the function as Alias-Name

CLC	macro
	b0bclr	FC
	endm

STC	macro
	b0bset	FC
	endm


NOT	macro	acc
	IFIDNI	<acc>, <A>
		xor	a, #0xff
	ELSE
		ERROR	please use NOT_ mem
	ENDIF
	endm

NEG	macro	acc
	IFIDNI	<acc>, <A>
		xor	a, #0xff
		add	a, #1
	ELSE
		ERROR	please use NEG_ mem
	ENDIF
	endm

;-------------------------------------------------------------------
;
;	Compare ACC with memory or immediate, if Above/Below/Equ then
;	jump to new address
;
;	CJxx	A, mem_imm, adr
;	CJxx	mem_imm, A, adr
;
;	*Note*	:	CF, ZF will be cahnge
;				adr may be 'RET'

Jmp_Ret	macro	adr
	IFIDNI	<adr>, <ret>
		ret
	ELSE
		jmp	adr
	ENDIF
	endm

CJAE	macro	v1, v2, adr
	IFIDNI	<v1>, <A>
		cmprs	a, v2
		b0bts0	FC
	ELSEIFIDNI	<v2>, <A>
		cmprs	a, v1
		b0bts1	FC
	ELSE
		ERROR	please use CJAE_/CJBE_ mem, mem, address
	ENDIF
	Jmp_Ret	<adr>
	endm

CJBE	macro	v1, v2, adr
	CJAE	<v2>, <v1>, <adr>
	endm

CJB	macro	v1, v2, adr
	CJA	<v2>, <v1>, <adr>
	endm

CJNE	macro	v1, v2, adr
	IFIDNI	<v1>, <A>
		cmprs	a, v2
	ELSEIFIDNI	<v2>, <A>
		cmprs	a, v1
	ELSE
		ERROR	please use CJNE_ mem, mem, address
	ENDIF
	Jmp_Ret	<adr>
	endm

;-------------------------------------------------------------------
;
;	Jxx	addr		:	Jump to address if condiction match.
;
;	DJNZ/IJNZ mem, addr	:	dec/inc memory, if mem not zero,
;					jump to another address.
;
;	*Note*			:	C, DC, Z not be changed,
;					2 cycle if no jump,
;					3 Cycle if jump to another address.
;					adr may be 'RET'

JZ	macro	adr
	b0bts0	FZ
	Jmp_Ret	<adr>
	endm

JNZ	macro	adr
	b0bts1	FZ
	Jmp_Ret	<adr>
	endm

JC	macro	adr
	b0bts0	FC
	Jmp_Ret	<adr>
	endm

JNC	macro	adr
	b0bts1	FC
	Jmp_Ret	<adr>
	endm

JDC	macro	adr
	b0bts0	FDC
	Jmp_Ret	<adr>
	endm

JNDC	macro	adr
	b0bts1	FDC
	Jmp_Ret	<adr>
	endm

JB1	macro	f, adr
	bts0	f
	Jmp_Ret	<adr>
	endm

JB0	macro	f, adr
	bts1	f
	Jmp_Ret	<adr>
	endm

DJNZ	macro	val, adr
	decms	val
	Jmp_Ret	<adr>
	endm

IJNZ	macro	val, adr
	incms	val
	Jmp_Ret	<adr>
	endm

;-------------------------------------------------------------------
;
;	RETxx		:	Ret if condiction match.
;
;	*Note*			:	C, DC, Z not be changed,
;					2 cycle if no ret,
;					3 Cycle if ret to another address.

RETZ	macro
	b0bts0	FZ
	ret
	endm

RETC	macro
	b0bts0	FC
	ret
	endm

RETNZ	macro
	b0bts1	FZ
	ret
	endm

RETNC	macro
	b0bts1	FC
	ret
	endm

;-------------------------------------------------------------------
;
;	SHL/SHR	mem	:	shift left/right memory
;	ROL/ROR mem	:	rotate left/right memory, bit0 <--> bit7
;	B2B/B2P		:	get one bit status, and set to another bit
;	*Note*		:	C flag will be changed, 2 - 4 Cycle

SHL	macro	mem
	b0bclr	FC
	rlcm	mem
	endm

SHR	macro	mem
	b0bclr	FC
	rrcm	mem
	endm

B2B	macro	f1, f2
	b0bclr	f2
	b0bts0	f1
	b0bset	f2
	endm

B2NB macro	f1, f2
	b0bclr	f2
	b0bts1	f1
	b0bset	f2
	endm

B2P	macro	f1, p1
	b0bts0	f1
	b0bset	p1
	b0bts1	f1
	b0bclr	p1
	endm

B2NP	macro	f1, p1
	b0bts1	f1
	b0bset	p1
	b0bts0	f1
	b0bclr	p1
	endm

ROL	macro	mem
	rlcm	mem
	B2B	FC, mem.0
	endm

ROR	macro	mem
	rrcm	mem
	B2B	FC, mem.7
	endm

RCL	macro	mem
	rlcm	mem
	endm

RCR	macro	mem
	rrcm	mem
	endm

;-------------------------------------------------------------------
;
;	DINT			// Global Interrupt Disable
;	DINT	P00/P01/P02	// General Interrupt Disable
;	DINT	TC0/TC1/T0/SIO	//
;
;	EINT	...		// Same as DINT
;
;	Note :	C, DC, Z not be changed, 1 or 2 Cycle

DINT	macro	int
	IFB	<int>
		b0bclr	fgie
	ELSE
		b0bclr	f&int&ien
		b0bclr	f&int&irq
	ENDIF
	endm

EINT	macro	int
	IFB	<int>
		b0bset	fgie
	ELSE
		b0bclr	f&int&irq
		b0bset	f&int&ien
	ENDIF
	endm

;;;ENDIF

;-------------------------------------------------------------------
; MACRO2.H
;-------------------------------------------------------------------

;-------------------------------------------------------------------
;
;	when operate between memory to memory, or immediate, the below
;	function are useful.
;
;	*Note* :	ACC will be changed, CF, ZF, DCF may be changed

MOV_	macro	mem, mem_val
	mov	a, mem_val
	mov	mem, a
	endm


OP3_	macro	op
op&_	macro	mem, mem_val, mem_aux
	ifdifi <a>, <mem_val>
		mov	a, mem_val
	endif
	ifb	<mem_aux>
		op	mem, a
	else
		op	a, mem_aux
		ifdifi	<a>, <mem>
			mov	mem, a
		endif
	endif
	endm
	endm

OP3_	ADD
OP3_	ADC
OP3_	AND
OP3_	OR
OP3_	XOR

OP4_	macro	op
op&_	macro	mem, mem_val, mem_aux
	ifb	<mem_aux>
		mov	a, mem
		op	a, mem_val
		mov	mem, a
	else
		ifdifi <a>, <mem_val>
			mov	a, mem_val
		endif
		op	a, mem_aux
		ifdifi	<a>, <mem>
			mov	mem, a
		endif
	endif
	endm
	endm

OP4_	SUB
OP4_	SBC

XCH_	macro	mem1, mem2
	mov	a, mem2
	xch	a, mem1
	mov	mem2, a
	endm

NOT_	macro	mem
	IFIDNI	<mem>, <A>
		xor	a, #0xff
	ELSE
		mov	a, #0xff
		xor	mem, a
	ENDIF
	endm

NEG_	macro	mem
	IFIDNI	<mem>, <A>
		xor	a, #0xff
		add	a, #1
	ELSE
		mov	a, #0
		sub	mem, a
	ENDIF
	endm

;-------------------------------------------------------------------
;
;	when compare between memory to memory, or immediate, the below
;	function are useful.
;
;	CJAE_/CJBE_/CJA_/CJB_/CJE_/CJNE_	mem1, mem2, addr_match_jump
;
;	Note :	ACC will be changed; C, Z flag will be changed
;				adr may be 'RET'

CJAE_	macro	v1, v2, adr
	mov	a, v1
	cmprs	a, v2
	b0bts0	FC

	Jmp_Ret	<adr>
	endm

CJA_	macro	v1, v2, adr
	mov	a, v2
	sub	a, v1
	b0bts1	FC

	Jmp_Ret	<adr>
	endm

CJBE_	macro	v1, v2, adr
	CJAE_	<v2>, <v1>, <adr>
	endm

CJB_	macro	v1, v2, adr
	CJA_	<v2>, <v1>, <adr>
	endm

CJNE_	macro	v1, v2, adr
	mov	a, v1
	cmprs	a, v2

	Jmp_Ret	<adr>
	endm

;-------------------------------------------------------------------
;
;	To check ACC in some range, example : #30h - #39h,
;	use BOUND_	30h, 39h, over_jmp_addr
;
;	Note :	ACC will be changed; C, DC, Z flag will be changed

BOUND_	expand	sm, la, adr
	add	a, #(0xFF - (la))
	b0bts0	FC
	Jmp_Ret	<adr>
	IFNB	<sm>
		IF	(sm) > 0
			add	a, #((la) - (sm) + 1)
			b0bts1	FC
			Jmp_Ret	<adr>
		ENDIF
	ENDIF
	endm

;;;ENDIF

;-------------------------------------------------------------------
; MACRO3.H
;-------------------------------------------------------------------
// The follow macro be defined by SONIX
// if you want to define new macro for yourself,
// please defined at other files, and will easy to maintain

// please don't set your file name as MACROx.H,
// because the name be reserved for new SONIX-MACRO file

;-------------------------------------------------------------------
;
;	LJMP	lar_far
;	...
;	LCALL	lar_far
;	...
;	ORG	0x4000
;	...
;	lab_far:

LJMP	macro	adr
	b0mov	pflag, #adr$J
	jmp		adr
	endm

LCALL	macro	adr
	b0mov	pflag, #adr$J
	call	adr
	b0mov	pflag, #(($>>10)!&0xF0)
	endm

;-------------------------------------------------------------------
;
;	...
;	@CHECK_REMAINS			; check the code page
;
;	ORG	0x4000
;	...
;	...
;	@CHECK_REMAINS	0x7000	; define the max code is 0x7000
;
;	ORG	0x7000
;	DW ... // define 0x1000 data
;
;	ORG	0x8000
;	...

@CHECK_REMAINS	macro	val
	IFB	<val>
		temp1	=	($ + 0x3FFF) !& 0xFC000
		temp2	=	temp1 - $
		ECHO	Remain %temp2 space before %temp1 page
	ELSEIF	$ > (val)
		temp1	=	$ - (val)
		ERROR	Over %temp1 space after val
	ELSE
		temp1	=	(val) - $
		ECHO	Remain %temp1 space before val
	ENDIF
	endm

;-------------------------------------------------------------------
;
;	...
;	@ORG	0x4000
;	...
;	...
;
;	@ORG	0x7000
;	DW ... // define 0x1000 data
;
;	@ORG	0x8000

@ORG	macro	val
	@CHECK_REMAINS	<val>
	ORG	val
	endm

;-------------------------------------------------------------------
;
;	mov		a, #n
;	@JMP_A	5		// follow 5 commands of jmp
;	jmp		here_a_0
;	jmp		here_a_1
;	jmp		here_a_2
;	jmp		here_a_3
;	jmp		here_a_4
;

@JMP_A_2ADR	macro	val,adr
  if	(($+4) !& 0xff00) !!= (($+3+(val*2)) !& 0xff00)
		jmp	($ | 0xff)
		ORG	($ | 0xff)
	ENDIF

	b0bclr	FC
	mov adr,a
	RLC adr
	b0add PCl ,a
	endm         
;-------------------------------------------------------------------
;
;	@SWITCH	A,        , here0, here1, here2, here3, ....
;	@SWITCH	A, err_jmp, here0, here1, here2, here3, ....
;
;	@SWITCH	mem,        , here0, here1, here2, here3, ....
;	@SWITCH	mem, err_jmp, here0, here1, here2, here3, ....
;

@SWITCH	expand	mm, ee, lab:VARARG
	IFDIFI	<mm>, <A>
		mov	a, mm
	ENDIF

	temp	=	0
	FOR	ll, <lab>
		temp	=	temp +1
	ENDM

	IFNB	<ee>
		cmprs	a, #temp
		b0bts0	FC
		jmp	ee
	ENDIF

	@JMP_A	temp

	FOR	ll, <lab>
		jmp	ll
	ENDM

	ENDM

;-------------------------------------------------------------------
;
;	XXX		MACRO
;			LOCAL	XX1, XX2
;			...
;		XX1:
;			...
;		XX2:
;			...
;			ENDM
;
;-------------------------------------------------------------------
/*
LOCAL	MACRO	ll:VARARG
		IFNDEF	@MS_LCL_TMP
				@MS_LCL_TMP	=	0
		ENDIF

		FOR		l, <ll>
				l	CATSTR	<@MS_LCL>, %@MS_LCL_TMP
				@MS_LCL_TMP	=	@MS_LCL_TMP + 1
		ENDM
		ENDM
*/
;-------------------------------------------------------------------
;
;	@INIT_PORT	P2, HL10UUII
;		// P2.7 = Out High, (Pull High)
;		// P2.6 = Out Low, (Pull High)
;		// P2.5 = Out High
;		// P2.4 = Out Low
;		// P2.3, P2.2 = Input Pull High
;		// P2.1, P2.0 = Input
;		;
;		; -> be generated
;		;	mov	a, #0F0h
;		;	mov	P2M, a
;		;	mov	a, #0C0h
;		;	mov	P2, a
;		;	mov	a, #0CCh
;		;	mov	P2UR, a

@INIT_PORT	macro	pt, str
	@s_TEMP1	=	0	// Mask
	@s_TEMP2	=	0	// Pull-Up
	@s_TEMP3	=	0	// Data
	FORC	c, <str>
		@s_TEMP1	=	@s_TEMP1 << 1
		@s_TEMP2	=	@s_TEMP2 << 1
		@s_TEMP3	=	@s_TEMP3 << 1

		IFIDNI		<c>, <I>
		ELSEIFIDNI	<c>, <U>
			@s_TEMP2	=	@s_TEMP2 + 1;
		ELSEIFIDNI	<c>, <H>
			@s_TEMP1	=	@s_TEMP1 + 1;
			@s_TEMP2	=	@s_TEMP2 + 1;
			@s_TEMP3	=	@s_TEMP3 + 1;
		ELSEIFIDNI	<c>, <L>
			@s_TEMP1	=	@s_TEMP1 + 1;
			@s_TEMP2	=	@s_TEMP2 + 1;
		ELSEIFIDNI	<c>, <1>
			@s_TEMP1	=	@s_TEMP1 + 1;
			@s_TEMP3	=	@s_TEMP3 + 1;
		ELSEIFIDNI	<c>, <0>
			@s_TEMP1	=	@s_TEMP1 + 1;
		ELSE
			ERROR	error str, only H/L/1/0/I/U can use
			EXITM
		ENDIF
	ENDM

	IF	P0 == pt
		IF	@s_TEMP1
			ERROR	P0 can't set to Output_Mode
		ENDIF
		IF	@s_TEMP2 == 0
			clr	pt&UR
		ELSE
			mov	a, #@s_TEMP2
			b0mov	pt&UR, a
		ENDIF
		EXITM
	ENDIF

	IF	@s_TEMP1 == 0
		clr	pt&M
	ELSE
		mov	a, #@s_TEMP1
		b0mov	pt&M, a
	ENDIF

	IF	@s_TEMP3 == 0
		clr	pt
	ELSEIF	@s_TEMP1 == @s_TEMP3
		b0mov	pt, a
	ELSE
		mov	a, #@s_TEMP3
		b0mov	pt, a
	ENDIF

	IF	@s_TEMP2 == 0
		clr	pt&UR
	ELSEIF	(@s_TEMP2 == @s_TEMP3) || (@s_TEMP2 == @s_TEMP1) !&!& (@s_TEMP3 == 0)
		b0mov	pt&UR, a
	ELSE
		mov	a, #@s_TEMP2
		b0mov	pt&UR, a
	ENDIF

	endm

ENDIF