**
** $Source: DH1:network/parnet/Sana2/Spar_device.asm,v $
** $State: Exp $
** $Revision: 37.1 $
** $Date: 93/08/24 20:41:25 $
** $Author: sap $
**
** Amiga SANA-II Example PARnet Device Driver
**
** Based on the SANA-II Example SLIP Device Driver by kcd.
**
** Portions (C) Copyright 1992 Commodore-Amiga, Inc.
**


	SECTION	firstsection

	NOLIST

	include	"exec/types.i"
	include	"exec/devices.i"
	include	"exec/initializers.i"
	include	"exec/memory.i"
	include	"exec/resident.i"
	include	"exec/io.i"
	include	"exec/ables.i"
	include	"exec/errors.i"
	include	"exec/tasks.i"
	include	"utility/tagitem.i"
	include	"dos/dos.i"
	include	"dos/dosextens.i"
	include	"dos/dostags.i"
	include	"devices/sana2.i"

	LIST
	include	"Spar_device.i"
        include "Spar_rev.i"

ABSEXECBASE	EQU	4	;Absolute location of the pointer to exec.library base

**
** Standard System Routines
**

	XREF	_DevOpen
	XREF	_DevClose
	XREF	_DevExpunge
	XREF	_DevBeginIO
	XREF	_DevAbortIO

**
** Other misc. routines
**
	XDEF	_ExtDeviceBase
	XDEF	_DevProcEntry
	XDEF	@IPToNum
	XDEF	_SANA2BuffCall
	XREF	_DevProcCEntry
	XREF	EndCode

**
** First executable location
**

FirstAddress:
	moveq	#-1,d0
	rts

**
** A romtag structure. Your load module will be scanned for
** this structure to discover magic constants about you
** (such as where to start running you from...).
**

** Most people will not need a priority and should leave it at zero.
** The RT_PRI field is used for configuring the roms.

SPARPRI   EQU   5

initDDescrip:
                        ; STRUCTURE RT,0
	DC.W	RTC_MATCHWORD		; UWORD	RT_MATCHWORD (Magic cookie)
	DC.L	initDDescrip		; APTR	RT_MATCHTAG  (Back pointer)
	DC.L	EndCode         ; APTR	RT_ENDSKIP   (To end of this hunk)
	DC.B	RTF_AUTOINIT		; UBYTE	RT_FLAGS     (magic-see "Init:")
	DC.B	VERSION			; UBYTE	RT_VERSION
	DC.B	NT_DEVICE		; UBYTE	RT_TYPE	     (must be correct)
	DC.B	SPARPRI			; BYTE	RT_PRI
	DC.L	SPARName		; APTR	RT_NAME	     (exec name)
	DC.L	idString		; APTR	RT_IDSTRING  (text string)
	DC.L	Init            ; APTR	RT_INIT
                        ; LABEL	RT_SIZE

** This is the name that the device will have

SPARName:	SPARDEVNAME

** This is an identifier tag to help in supporting the device
** format is 'name version.revision (dd MON yyyy)',<cr>,<lf>,<null>

idString:	VSTRING

** Force word alignment

	CNOP	0,4

** The romtag specified that we were "RTF_AUTOINIT". This means
** that the RT_INIT structure member points to one of these
** tables below. If the AUTOINIT bit was not set then RT_INIT
** would point to a routine to run.

Init:
	DC.L	SPARDev_Sizeof	; data space size
	DC.L	DevFuncTable	; pointer to function initializers
	DC.L	DevDataTable	; pointer to data initializers
	DC.L	DevInit		; routine to run

DevFuncTable:
	dc.l	_DevOpen
	dc.l	_DevClose
	dc.l	_DevExpunge
	dc.l	DevReserved
	dc.l	_DevBeginIO
	dc.l	_DevAbortIO
	dc.l	-1

** The data table initializes static data structures. The format is
** specified in exec/InitStruct routine's manual page. The
** INITBYTE/INITWORD/INITLONG macros are in the file "exec/initializers.i".
** The first argument is the offset from the device base for this
** byte/word/long. The second argument is the value to put in that cell.
** The table is null terminated.

DevDataTable:
	INITBYTE	LN_TYPE,NT_DEVICE	;Must be LN_TYPE!
	INITLONG	LN_NAME,SPARName
	INITBYTE	LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED
	INITWORD	LIB_VERSION,VERSION
	INITWORD	LIB_REVISION,REVISION
	dc.l		0

_ExtDeviceBase	dc.l	0

**
** initRoutine
**
** This routine gets called after device has been allocated.
** The device pointer is in d0, the AmigaDOS segment list in a0.
** If it returns it's device pointer, then the device will be linked
** into the devices list. If it returns NULL, then the device will be
** unloaded.
**
** This routine is single threaded
**
** Register Usage
**
** a3 - Pointer to temporary RAM
** a4 - Pointer to expansion.library base
** d0 - Pointer to device struct
** a6 - Pointer to Exec Base

DevInit:
	movem.l	a0/a5,-(sp)
	movea.l	d0,a5
;	move.w	#REVISION,LIB_REVISION(a5)	;already done in DevDataTable
	move.l	a6,sd_SysLib(a5)	;save a pointer to exec
	move.l	a0,sd_SegList(a5)	;save a pointer to our loaded code
	lea.l	sd_Lock(a5),a0		;make sure the Open() function
	jsrlib	InitSemaphore		;will be single-threaded.
	move.l	a5,d0			;return the device pointer
	movem.l	(sp)+,a0/a5
	rts

DevReserved:
	moveq.l	#0,d0
	rts

@IPToNum:
	movem.l	d2,-(sp)
	bsr	StrToNum
	lsl.w	#8,d0
	move.w	d0,d2
	bsr	StrToNum
	move.b	d0,d2
	swap	d2
	bsr	StrToNum
	lsl.w	#8,d0
	move.w	d0,d2
	bsr	StrToNum
	move.b	d0,d2
	move.l	d2,d0
	movem.l	(sp)+,d2
	rts

StrToNum:
	moveq	#0,d0
	moveq	#0,d1
1$	move.b	(a0)+,d1
	cmp.b	#'0',d1
	blo	2$
	cmp.b	#'9',d1
	bhi	2$
	sub.b	#'0',d1
	mulu	#10,d0
	add.w	d1,d0
	bra	1$
2$	rts

_SANA2BuffCall:
	jmp	(a2)

_DevProcEntry:
	movea.l	_ExtDeviceBase(pc),a6
	jmp	_DevProcCEntry


	END
