; $Id: device1.a,v 1.56 1996/12/21 23:34:35 Rhialto Rel $
; $Log: device1.a,v $
; Revision 1.56  1996/12/21  23:34:35  Rhialto
; Add own BeginIO since the new DICE one seems to be buggy.
;
; Revision 1.55  1993/12/30  22:45:10  Rhialto
; Change return code when loaded from CLI.
; Remove xref _InitTable.
; Freeze for MAXON5.
;
; Revision 1.54  1993/06/24  04:56:00  Rhialto
; Switch to RTF_AUTOINIT, saves a few bytes. DICE 2.07.54R.
;
; Revision 1.53  92/10/25  02:08:55  Rhialto
; Import UNITB_ACTIVE and HANDLE_IO_QUICK.
;
; Revision 1.51  92/04/17  15:41:30  Rhialto
; Freeze for MAXON3.
;
; Revision 1.46  91/10/06  18:25:18  Rhialto
;
; Freeze for MAXON
;
; Revision 1.42  91/06/14  00:08:48  Rhialto
; DICE conversion
;
	    include	"c.i"
;;;;
;
;   Some constants that need to be modified on specific versions

RTPRI	    equ 	0

;;;;
;
; The first executable location. This should return an error in case
; someone tried to run you as a program (instead of loading you as a
; device)

	section text,code

	moveq.l #-1,d0
	rts

;;;;
;
; A romtag structure. Both "exec" and "ramlib" look for this structure to
; discover magic constants about you (such as where to start running you
; from...).
;
	xref	_DevName
	xref	_idString
	xdef	_RomTag
_RomTag:
	dc.w	RTC_MATCHWORD
	dc.l	_RomTag 	; rt_MatchTag
	dc.l	EndCode 	; rt_EndSkip
	dc.b	RTF_AUTOINIT	; rt_Flags
	dc.b	VERSION 	; rt_Version
	dc.b	NT_DEVICE	; rt_Type
	dc.b	RTPRI		; rt_Pri
	dc.l	_DevName	; rt_Name
	dc.l	_idString	; rt_IdString
	dc.l	Init		; rt_Init

	xref	@Init
Init:
	dc.l	md_SIZEOF	; size of data portion of Device
	dc.l	LibVectors	; pointer to function initialisers
	dc.l	InitTable	; pointer to data initialisers
	dc.l	@Init		; routine to run (d0: dev ptr, a0: seglist)

	xref	 @DevOpen,@DevClose,@DevExpunge
	xref	 @DevBeginIO
	xref	 @DevAbortIO
LibVectors:
	dc.l	@DevOpen,@DevClose,@DevExpunge,LibNull
	dc.l	@DevBeginIO
	dc.l	@DevAbortIO
	dc.l	-1

INITBYTE	MACRO	; &offset,&value
		IFLE	(\1)-255        ;If offset <=255
		DC.B	$a0,\1		;use byte offset
		DC.B	\2,0
		MEXIT			;exit early
		ENDC
		DC.B	$e0,0
		DC.W	\1
		DC.B	\2,0
		ENDM

INITWORD	MACRO	; &offset,&value
		IFLE	(\1)-255        ;If offset <=255
		DC.B	$90,\1		;use byte offset
		DC.W	\2
		MEXIT			;exit early
		ENDC
		DC.B	$d0,0
		DC.W	\1
		DC.W	\2
		ENDM

INITLONG	MACRO	; &offset,&value
		IFLE	(\1)-255        ;If offset <=255
		DC.B	$80,\1		;use byte offset
		DC.L	\2
		MEXIT			;exit early
		ENDC
		DC.B	$c0,0
		DC.W	\1
		DC.L	\2
		ENDM

InitTable:
	INITBYTE ln_Type,NT_DEVICE
	INITLONG ln_Name,_DevName
	INITBYTE dev_Flags,LIBF_CHANGED!LIBF_SUMUSED,
	INITWORD dev_Version,VERSION
	INITWORD dev_Revision,REVISION
	INITLONG dev_IdString,_idString
	dc.w	0

;;;;
;
; Here begin the system interface commands. When the user calls
; OpenDevice/CloseDevice/RemDevice, this eventually gets trahslated into
; a call to the following routines (Open/Close/Expunge).  Exec has
; already put our device pointer in A6 for us.	Exec has turned off task
; switching while in these routines (via Forbid/Permit), so we should not
; take too long in them.
;
; These glue routines are not necessary when using the special
; __D0 keywords of DICE. When we do use these, don't forget to make sure
; the C routines expect the arguments on the stack (i.e. __stkargs)

	ifne	0
	xdef	Init
	xref	_Init
Init:				;a0=segment list
	move.l	A0,-(sp)
	jsr	_Init
	addq	#4,sp
	rts

	xdef	DevOpen
	xref	_DevOpen
DevOpen:			;d0=unitnum,d1=flags,a1=ioreq,a6=device
	movem.l D0-D1/A1/A6,-(sp)
	jsr	_DevOpen
	lea	16(sp),sp
	rts

	xdef	DevClose
	xref	_DevClose
DevClose:			;a1=ioreq,a6=device
	movem.l A1/A6,-(sp)
	jsr	_DevClose
	addq	#8,sp
	rts

	xdef	DevExpunge
	xref	_DevExpunge
DevExpunge:			;a6=device
	movem.l A6,-(sp)
	jsr	_DevExpunge
	addq	#4,sp
	rts

	xdef	DevBeginIO
	xref	_DevBeginIO
DevBeginIO:			;a1=ioreq,a6=device
	movem.l A1/A6,-(sp)
	jsr	_DevBeginIO
	addq	#8,sp
	rts

	xdef	DevAbortIO
	xref	_DevAbortIO
DevAbortIO:			;a1=ioreq,a6=device
	movem.l A1/A6,-(sp)
	jsr	_DevAbortIO
	addq	#8,sp
	rts
	endc

LibNull:
	clr.l	d0
	rts

	ifne	HANDLE_IO_QUICK
;;;;
;
;   C interface to the atomic set bit and test old value instruction.
;
;   Called as	BSET_ACTIVE(byte *address).
;
;   Old value of the bit returned all over d0.w

	xdef	_BSET_ACTIVE
	xdef	@BSET_ACTIVE
_BSET_ACTIVE:
	move.l	4(sp),a0
@BSET_ACTIVE:
	bset	#UNITB_ACTIVE,(a0)         ; 0 UNITB_ACTIVE
	sne	d0
	rts
	endc	; HANDLE_IO_QUICK

		;   BeginIO(ior)

		section text,code

		xdef	_hyper_BeginIO
		xdef	_BeginIO
		xdef	@BeginIO

_hyper_BeginIO:
_BeginIO:
		move.l	4(sp),A0
@BeginIO:
		move.l	A6,-(sp)
		move.l	A0,A1
		move.l	$14(A0),A6   ; io_Device
		jsr	-30(A6)
		move.l	(sp)+,A6
		rts

EndCode
	end
