; File name:	URAn_XB.S	Revised:  1991.07.04
; Creator:	U.R.Andersson	Created:  1991.05.07
; (c)1991 by:	U.R.Andersson	All rights reserved
; Released as:	FREEWARE	(NB: commercial sales forbidden!)
;
; File purpose:	Defines 9 macros to implement XBRA function protocol
;
;   The first 4 alter no registers
; XB_define	xbstruct,xbra_id	Defines header for XBRA function code
; XB_gonext	xbstruct		Links to next XBRA function in chain
; XB_gonext_d	xbstruct		Links to next XBRA function in chain
; XB_donext_d	xbstruct		Calls next XBRA subroutine in chain
;
;   The next 2 alter only the choosen "areg"
; Find_Frame	areg			areg->exception argument -6
; XB_donext	xbstruct,areg		Calls next XBRA function in chain
;
;   The next 3 affect d0-d2/a0-a2, since they use XBIOS Supexec
; XB_check	xbstruct,root		d0= found_codead/zero  flagged NE/EQ
;   -"-           -"-			a0->found_vector/last_vector 
; XB_install	xbstruct,root		Installs xbstruct in chain(root)
; XB_remove	xbstruct,root		Removes xbstruct from chain(root)
;
; Legal forms for xbstruct & root here are mostly the same as for LEA & PEA,
;   except that for XB_define "xbstruct" is a free name for the new structure.
; "xbstruct" always refers to the first byte of the entire structure.
; "xbra_id" is a 4-character (longword) string
; "areg" is a free address register of your choice.
; XB_gonext_d & XB_donext_d are faster versions of XB_gonext & XB_donext,
;   but can only handle address modes where "xbstruct" begins with identifier.
;   eg: "XB_donext_d  my_ikbd_sub(pc)"  but  "XB_donext  (a5)+")
; Find_Frame makes XBRA exception functions (eg: gemdos etc.) TT compatible.
;
;	Macro definitions (with support variables)
;
;
Find_Frame	macro	areg
	btst	#5,(sp)
	beq.s	.user\@
	move.l	sp,\1
	tst	$59E.w
	beq.s	.framed\@
	addq	#2,\1
	bra.s	.framed\@
.user\@:
	move	USP,\1
	subq	#6,\1
.framed\@:
	endm
;
;
XB_define	macro	xbstructname,xbra_id
\1:	dc.l	'XBRA',\2,0
	endm
;
;
XB_donext_d	macro	xbstruct
	move.l	8+\1,-(sp)
	jsr	(sp)+
	endm
;
;
XB_donext	macro	xbstruct,areg
	lea	\1,\2
	move.l	8(\2),\2
	jsr	(\2)
	endm
;
;
XB_gonext_d	macro	xbstruct
	move.l	8+\1,-(sp)
	rts
	endm
;
;
XB_gonext	macro	xbstruct
	movem.l	a0-a1,-(sp)
	lea	\1,a0
	move.l	8(a0),4(sp)
	move.l	(sp)+,a0
	rts
	endm
;
;
zzXBccnt	set	0
;
XB_check	macro	xbstruct,root
	ifne	zzXBccnt=0
	bra	zzXBcend
zzXBcsub:
	move.l	8(sp),a0
	move.l	12(sp),a1
zzXBchlp:
	move.l	a1,d1
	move.l	(a1),d0
	beq.s	zzXBcrts
	move.l	d0,a1
	subq.l	#4,a1
	clr.l	d0
	cmpi.l	#'XBRA',-8(a1)
	bne.s	zzXBcrts
	move.l	-4(a1),d0
	cmp.l	4(a0),d0
	bne.s	zzXBchlp
zzXBcrts:	;d1->last legal vector in chain or vector for current XBRA
;	...	;d0= zero or code address of current XBRA
	move.l	d1,a0
	rts	;d0=zero/codeadr of found XBRA a0->last/found vector
zzXBcend:
	endc
	pea	\2
	pea	\1
	pea	zzXBcsub
	move	#$26,-(sp)
	trap	#14
	add.w	#14,sp
	tst.l	d0
zzXBccnt	set	zzXBccnt+1
	endm
;
;
zzXBicnt	set	0
;
XB_install	macro	xbstruct,root
	ifne	zzXBicnt=0
	bra	zzXBiend
zzXBisub:
	move.l	8(sp),a0
	move.l	12(sp),a1
	XB_check	(a0),(a1)
	bne	zzXBirts
	move.l	8(sp),a0
	move.l	12(sp),a1
	lea	8(a0),a0
	move	SR,-(sp)
	ori	#$0700,SR
	move.l	(a1),(a0)+
	move.l	a0,(a1)
	move	(sp)+,SR
zzXBirts:
	rts	
zzXBiend:
	endc
	pea	\2
	pea	\1
	pea	zzXBisub
	move	#$26,-(sp)
	trap	#14
	add.w	#14,sp
zzXBicnt	set	zzXBicnt+1
	endm
;
;
zzXBrcnt	set	0
;
XB_remove	macro	xbstruct,root
	ifne	zzXBrcnt=0
	bra	zzXBrend
zzXBrsub:
	move.l	8(sp),a0
	move.l	12(sp),a1
	XB_check	(a0),(a1)
	beq.s	zzXBrrts
	move.l	(a0),a1
	move.l	-4(a1),(a0)
zzXBrrts:
	rts	
zzXBrend:
	endc
	pea	\2
	pea	\1
	pea	zzXBrsub
	move	#$26,-(sp)
	trap	#14
	add.w	#14,sp
zzXBrcnt	set	zzXBrcnt+1
	endm
;
;
; End of file:	URAn_XB.S
