		incdir	includes:
		include	exec/exec.i
		include	exec/exec_lib.i
		include	resources/cia_lib.i
		include	hardware/cia.i

		include	libraries/configvars.i
		include	libraries/expansion.i
		include	libraries/expansion_lib.i
		include	devices/truesound.i

		STRUCTURE MYDEV,LIB_SIZE
		UBYTE	MD_FLAGS
		UBYTE	MD_PAD1
		UWORD	MD_PAD2
		ULONG	MD_SEGLIST
		LABEL	MYDEV_SIZEOF


		STRUCTURE	TRUESOUND,0
		APTR	L3_CONFBASE
		APTR	L3_BASEADR
		APTR	L3_CURRENTREQ
		APTR	L3_CURRENTPOS
		APTR	L3_CURRENTLEFT
		UWORD	L3_CONFVAL
		UWORD	L3_PAUSED
		UWORD	L3_UNITOPENCNT
		UBYTE	L3_I2CSTATE
		UBYTE	L3_PAD1
		STRUCT	L3_WRITELIST,ML_SIZE
		LABEL	TRUESOUND_SIZEOF


;--Constants
REVISION=2
VERSION=1
MYPRI=0
UNITS=4

CREG		EQU	6*2+1
CREG2		EQU	7*2+1
DREG		EQU	0


;------------------------------------------------------------------------

j		moveq	#0,d0	;Om någon skulle försöka starta oss!
		rts

initddescript	dc.w	RTC_MATCHWORD	;RT_MATCHWORD
		dc.l	initddescript	;RT_MATCHTAG
		dc.l	endofcode	;RT_ENDSKIP
		dc.b	RTF_AUTOINIT	;RT_FLAGS
		dc.b	VERSION		;RT_VERSION
		dc.b	NT_DEVICE	;RT_TYPE
		dc.b	MYPRI		;RT_PRI
		dc.l	myname
		dc.l	idstring
		dc.l	init



myname		dc.b	"truesound.device",0
		dc.b	"$VER: "
idstring	dc.b	"truesound.device ",(VERSION+"0"),".",(REVISION+"0")
		dc.b	" (1.11.97)",13,10,0
		cnop	0,4

init		dc.l	MYDEV_SIZEOF
		dc.l	functable
		dc.l	datatable
		dc.l	initroutine


;--Funktion table
functable	dc.l	open	;open		-6
		dc.l	close	;close		-12
		dc.l	expunge	;expunge	-18
		dc.l	resvec	;reserved	-24
		dc.l	beginio	;BeginIO 	-30
		dc.l	abortio	;AbortIO	-36
		dc.l	-1	;marks end of list

;---Data table
datatable	dc.l	0
		dc.l	0
		dc.b	NT_DEVICE
		dc.b	0
		dc.l	myname

		dc.b	LIBF_SUMUSED!LIBF_CHANGED ;UBYTE   LIB_FLAGS
		dc.b	0		;UBYTE   LIB_pad
		dc.w	0		;UWORD   LIB_NEGSIZE
		dc.w	0		;UWORD   LIB_POSSIZE
		dc.w	VERSION		;UWORD   LIB_VERSION
		dc.w	REVISION	;UWORD   LIB_REVISION
		dc.l	idstring	;APTR    LIB_IDSTRING
		dc.l	0		;ULONG   LIB_SUM
		dc.w	0		;UWORD   LIB_OPENCNT

_SysBase	dc.l	0

;========================================================================
;---initroutine---
;d0=devicebase
;a0=seglist
;
;return d0
;devicebase=ok
;0=error
;========================================================================

initroutine	movem.l	d1-d7/a0-a6,-(sp)
		move.l	d0,a5
		move.w	#VERSION,LIB_VERSION(a5)
		move.w	#REVISION,LIB_REVISION(a5)

		move.l	a0,MD_SEGLIST(a5)
		move.l	4.w,_SysBase

		move.l	a5,-(sp)
		bsr.w	setupdevice
		move.l	(sp)+,a5
		tst.l	d0
		beq.b	.ok
		moveq	#0,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

.ok		move.l	a5,d0
		movem.l	(sp)+,d1-d7/a0-a6
		rts

;========================================================================
;---opendevice---   guaranteed to be single threaded
;d0=unit
;d1=flags
;a1=io-request
;a6=devicebase
;
;return IO_ERROR
;0=ok
;!0=errorcode
;========================================================================
open		cmp.l	#UNITS,d0
		bge.b	.error

		tst.w	LIB_OPENCNT(a6)
		bne.b	.timeralloced

		move.l	a1,-(sp)
		bsr.w	alloctimer		;start timer if opencnt>0
		move.l	(sp)+,a1
		tst.l	d0
		bne.b	.error

.timeralloced	move.l	d0,d1
		mulu	#TRUESOUND_SIZEOF,d1
		move.l	d1,a0
		add.l	#unitdata,a0
		move.l	a0,IO_UNIT(a1)

		tst.w	L3_UNITOPENCNT(a0)	;has this unit been opened?
		bne.b	.openedbefore
		move.l	a0,-(sp)
		bsr.w	openunit
		move.l	(sp)+,a0
		tst.l	d0
		bne.b	.error

.openedbefore	addq.w	#1,L3_UNITOPENCNT(a0)
		addq.w	#1,LIB_OPENCNT(a6)
		bclr	#LIBB_DELEXP,MD_FLAGS(a6)
		rts

.error		move.b	#IOERR_OPENFAIL,IO_ERROR(a1)
		rts

;========================================================================
;---closedevice---   guaranteed to be single threaded
;a6=devicebase
;a1=io-request
;
;return d0
;0=do nothing
;seglist=unload device
;========================================================================
close		movem.l	d2-d5/a2-a5,-(sp)
		move.l	IO_UNIT(a1),a0

		moveq	#-1,d2
		move.l	d2,IO_UNIT(a1)
		move.l	d2,IO_DEVICE(a1)

		subq.w	#1,L3_UNITOPENCNT(a0)
		bne.b	.noresetcard		;If this unit has opencnt=0
		move.l	L3_BASEADR(a0),a0	;then reset card!
		move.b	#$80,CREG(a0)

.noresetcard	clr.l	d0
		subq.w	#1,LIB_OPENCNT(a6)
		bne.b	.end

		bsr.w	freetimer		;release timer if opencnt=0
		clr.l	d0

		btst	#LIBB_DELEXP,MD_FLAGS(a6)
		beq.b	.end	
		bsr.b	expunge

.end		movem.l	(sp)+,d2-d5/a2-a5
		rts

;========================================================================
;---expunge---   guaranteed to be single threaded
;a6=devicebase
;
;return d0
;0=do nothing
;seglist=unload device
;========================================================================
expunge		movem.l	d2-d5/a2-a6,-(sp)
		move.l	a6,a5
		tst.w	LIB_OPENCNT(a5)
		beq.b	.remove

		bset	#LIBB_DELEXP,MD_FLAGS(a5)
		moveq	#0,d0
		bra.s	.end

.remove		bsr.w	cleanupdevice
		move.l	MD_SEGLIST(a5),d2
		move.l	a5,a1
		REMOVE
		move.l	a5,a1
		clr.l	d0
		move.w	LIB_NEGSIZE(a5),d0
		suba.l	d0,a1
		add.w	LIB_POSSIZE(a5),d0
		move.l	_SysBase(pc),a6
		jsr	_LVOFreeMem(a6)
		move.l	d2,d0

.end		movem.l	(sp)+,d2-d5/a2-a6
		rts

;========================================================================
;---beginio---
;a6=devicebase
;a1=iorequest
;========================================================================
beginio		movem.l	a6,-(sp)

		clr.b	IO_ERROR(a1)
		move.b	#NT_MESSAGE,LN_TYPE(a1)

		clr.l	d0
		move.w	IO_COMMAND(a1),d0
		cmp.l	#L3CMD_FINISH+1,d0	;Is IO_COMMAND to high?
		bge.b	.unknowncmd
		add.w	d0,d0
		lea	.cmdtable(pc),a0
		add.w	d0,d0
		move.l	(a0,d0.w),a0
		cmp.l	#0,a0			;Unsupported command?
		beq.b	.unknowncmd
		jsr	(a0)			;Jump to CMD-code
		bra.b	.cont

.unknowncmd	move.b	#IOERR_NOCMD,IO_ERROR(a1)
		clr.b	IO_FLAGS(a1)
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)

.cont		movem.l	(sp)+,a6
		rts


		cnop	0,4
.cmdtable	dc.l	0		;0	CMD_INVALID
		dc.l	cmd_reset	;1	CMD_RESET
		dc.l	0		;2	*CMD_READ
		dc.l	cmd_write	;3	CMD_WRITE
		dc.l	0		;4	*CMD_UPDATE
		dc.l	0		;5	*CMD_CLEAR
		dc.l	cmd_stop	;6	CMD_STOP
		dc.l	cmd_start	;7	CMD_START
		dc.l	0		;8	*CMD_FLUSH
		dc.l	l3cmd_setvol	;9	L3CMD_SETVOL
		dc.l	l3cmd_loadcodec	;a	L3CMD_LOADCODEC
		dc.l	l3cmd_gomp2	;b	L3CMD_GOMP2


;========================================================================
;---abortio---
;a6=devicebase
;a1=iorequest
;========================================================================
abortio		movem.l	a2/a6,-(sp)
		move.l	_SysBase(pc),a6
		jsr	_LVODisable(a6)

		move.l	IO_UNIT(a1),a2
		lea	L3_WRITELIST(a2),a0	;queued IO?
		move.l	a1,-(sp)
		bsr.b	removeioreq
		move.l	(sp)+,a1


		cmp.l	L3_CURRENTREQ(a2),a1
		bne.b	.notcurr		;abort active IO?

		clr.l	L3_CURRENTREQ(a2)
		clr.l	L3_CURRENTPOS(a2)
		clr.l	L3_CURRENTLEFT(a2)

		move.b	#IOERR_ABORTED,IO_ERROR(a1)
		jsr	_LVOReplyMsg(a6)

		lea	L3_WRITELIST(a2),a0
		jsr	_LVORemHead(a6)
		tst.l	d0			;IO queued?
		beq.b	.notcurr

		move.l	d0,a1
		move.l	a1,L3_CURRENTREQ(a2)
		move.l	IO_DATA(a1),L3_CURRENTPOS(a2)
		move.l	IO_LENGTH(a1),L3_CURRENTLEFT(a2)
		addq.l	#2,L3_CURRENTLEFT(a2)

.notcurr	jsr	_LVOEnable(a6)
		movem.l	(sp)+,a2/a6
		rts

;========================================================================
removeioreq	;remova IO-request (a1) om det finns i listan (a0).

		move.l	a0,-(sp)
		bsr.b	nodeinlist
		move.l	(sp)+,a0
		tst.l	d0
		beq.b	.exit
		move.l	a1,-(sp)
		move.l	_SysBase(pc),a6
		jsr	_LVORemove(a6)
		move.l	(sp)+,a1
		move.b	#IOERR_ABORTED,IO_ERROR(a1)
		jsr	_LVOReplyMsg(a6)
.exit		rts


nodeinlist	;d0 BOOL=nodeinlist(a0 list, a1 node)
		move.l	LN_SUCC(a0),a0
		cmp.l	a1,a0
		beq.b	.found
		tst.l	(a0)
		bne.b	nodeinlist
		moveq	#0,d0
		rts

.found		move.l	a0,d0
		rts


;========================================================================
resvec		moveq	#0,d0
		rts

;========================================================================
;---cmd_stop---
;a1=IORequest
;========================================================================
cmd_write	move.l	a6,-(sp)
		move.l	_SysBase(pc),a6
		jsr	_LVODisable(a6)

		clr.b	IO_FLAGS(a1)		;no quick io!
		bclr	#0,IO_LENGTH+3(a1)

		move.l	IO_UNIT(a1),a0
		tst.l	L3_CURRENTREQ(a0)
		beq.b	.emptylist

		lea	L3_WRITELIST(a0),a0
		jsr	_LVOAddTail(a6)
		jsr	_LVOEnable(a6)
		move.l	(sp)+,a6
		rts

.emptylist	move.l	a1,L3_CURRENTREQ(a0)
		move.l	IO_DATA(a1),L3_CURRENTPOS(a0)
		move.l	IO_LENGTH(a1),d0
		addq.l	#2,d0
		move.l	d0,L3_CURRENTLEFT(a0)
		jsr	_LVOEnable(a6)
		move.l	(sp)+,a6
		rts


;========================================================================
;---cmd_stop---
;a1=IORequest
;========================================================================
cmd_stop	move.l	IO_UNIT(a1),a0
		move.w	#1,L3_PAUSED(a0)
		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts


;========================================================================
;---cmd_start---
;a1=IORequest
;========================================================================
cmd_start	move.l	IO_UNIT(a1),a0
		move.w	#0,L3_PAUSED(a0)
	
		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts

;========================================================================
;---cmd_reset---
;a1=IORequest
;========================================================================
cmd_reset	move.l	a1,-(sp)
		move.l	IO_UNIT(a1),a0

		move.l	L3_BASEADR(a0),a1	;reset card
		move.b	#$80,CREG(a1)

		move.l	L3_CONFBASE(a0),a1	;reconfigure card
		move.w	L3_CONFVAL(a0),d0
		move.b	d0,(a1)
		move.l	L3_BASEADR(a0),a1
		move.b	#$00,CREG(a1)


		move.l	(sp)+,a1
		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts


;========================================================================
;---l3cmd_setvol---
;a1=IORequest
;========================================================================
l3cmd_setvol	move.l	IO_DATA(a1),d0
		move.l	IO_UNIT(a1),a0
		move.l	a1,-(sp)
		bsr.w	l3setvol
		move.l	(sp)+,a1

		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts

;========================================================================
;---l3cmd_loadcodec---
;a1=IORequest
;========================================================================
l3cmd_loadcodec	move.l	a1,-(sp)

		move.l	IO_UNIT(a1),a0
		move.l	IO_LENGTH(a1),d0
		move.l	IO_DATA(a1),a1
		bsr.w	L3LoadCodec

		move.l	(sp)+,a1

		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts


;========================================================================
;---l3cmd_gomp2---
;a1=IORequest
;========================================================================
l3cmd_gomp2	move.l	a1,-(sp)
		move.l	IO_UNIT(a1),a0

		lea	l3_l2codec(pc),a1
		move.w	#l3_l2codecend-l3_l2codec,d0
		bsr.w	L3LoadCodec

		move.l	(sp)+,a1


		btst	#IOB_QUICK,IO_FLAGS(a1)
		bne.b	.quickio
		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)
.quickio	rts

;========================================================================
ciaint		dc.l	0
		dc.l	0
		dc.b	0
		dc.b	32
		dc.l	ciaintname
		dc.l	0
		dc.l	ciaintcode

ciaintname	dc.b	"truesound.device interrupt",0
		cnop	0,4

;------------------------------------------------------------------------
ciaintcode	movem.l	d0-d2/a0-a2,-(sp)
		lea	unitdata(pc),a2

		moveq	#UNITS-1,d2

.checkloop	tst.l	L3_CURRENTREQ(a2)
		beq.w	.noreq

		tst.w	L3_PAUSED(a2)
		bne.b	.noreq
		bsr.b	int_fillunit
.noreq		lea	TRUESOUND_SIZEOF(a2),a2
		dbf	d2,.checkloop

.exit		movem.l	(sp)+,d0-d2/a0-a2
		rts

;========================================================================
;---int_fillunit---
;a2=unit
;========================================================================
int_fillunit:	move.l	L3_BASEADR(a2),a0
		move.l	L3_CURRENTPOS(a2),a1

.loop		btst	#1,CREG2(a0)
		beq.b	.nodreq

		move.w	(a1)+,d0
		subq.l	#2,L3_CURRENTLEFT(a2)
		beq.b	.dataslut
		ror.w	#8,d0

		move.w	d0,(a0)

		rept 10			;16 bit IO-recovery wait
		btst	#6,$bfe001
		endr

		bra.b	.loop

.nodreq		move.l	a1,L3_CURRENTPOS(a2)
.exit		rts

.dataslut	move.l	L3_CURRENTREQ(a2),a1
		move.l	a6,-(sp)

		move.l	_SysBase(pc),a6
		jsr	_LVOReplyMsg(a6)

		clr.l	L3_CURRENTREQ(a2)
		clr.l	L3_CURRENTPOS(a2)
		clr.l	L3_CURRENTLEFT(a2)
		
		lea	L3_WRITELIST(a2),a0
		jsr	_LVORemHead(a6)
		move.l	(sp)+,a6
		tst.l	d0
		beq.b	.exit

		move.l	d0,a1
		move.l	a1,L3_CURRENTREQ(a2)
		move.l	IO_DATA(a1),L3_CURRENTPOS(a2)
		move.l	IO_LENGTH(a1),L3_CURRENTLEFT(a2)
		addq.l	#2,L3_CURRENTLEFT(a2)
		bra.w	int_fillunit

;========================================================================
;---setupdevice--- executed on load of device
;========================================================================
setupdevice	lea	expansionname(pc),a1
		moveq	#0,d0
		move.l	_SysBase(pc),a6
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,_ExpansionBase
		beq.b	.nolib

		sub.l	a0,a0
		move.l	#2150,d0
		move.l	#1,d1
		move.l	_ExpansionBase(pc),a6
		jsr	_LVOFindConfigDev(a6)	;Find the gg2+'s base.
		tst.l	d0
		beq.b	.noboard

		move.l	d0,a0
		move.l	cd_BoardAddr(a0),ggbase
		
.noboard
.nolib		move.l	_ExpansionBase,a1
		move.l	_SysBase(pc),a6
		jsr	_LVOCloseLibrary(a6)
		tst.l	ggbase
		beq.b	.error

		moveq	#0,d0
		rts

.error		moveq	#-1,d0
		rts

_ExpansionBase	dc.l	0
expansionname	dc.b	"expansion.library",0
		cnop	0,4

;========================================================================
;---openunit---
;d0=unit
;a1=iorequest
;========================================================================
openunit:	move.l	a1,-(sp)
		move.l	IO_UNIT(a1),a0

		lea	L3_WRITELIST(a0),a1
		NEWLIST	a1

		move.l	ggbase(pc),a1
		add.l	confbases(pc,d0),a1
		cmp.b	#$ff,(a1)
		beq.b	.error
		move.l	a1,L3_CONFBASE(a0)

		clr.w	d1

		move.w	confvals(pc,d0),d1
		move.w	d1,L3_CONFVAL(a0)
		move.b	d1,(a1)
		move.l	ggbase(pc),a1
		add.l	cardbases(pc,d0),a1
		move.l	a1,L3_BASEADR(a0)

		move.b	#$00,CREG(a1)
		move.l	(sp)+,a0

		moveq	#0,d0
		rts

.error		moveq	#-1,d0
		rts

confvals	dc.w	$200/8, $210/8, $220/8, $230/8
		cnop	0,4
confbases	dc.l	$3ff, $3fd, $3fb, $3f9
cardbases	dc.l	$400, $420, $440, $460


;========================================================================
cleanupdevice	moveq	#0,d0		;anropas innan expunge
		rts

;=========================================================================
alloctimer	movem.l	a5-a6,-(sp)
		lea	ciaaname(pc),a1		;öppna cia reosource
		move.l	_SysBase(pc),a6
		jsr	_LVOOpenResource(a6)
		move.l	d0,_CIAABase
		beq.b	.err

		moveq	#CIAICRB_TA,d0		;vårt ciatimer int
		lea	ciaint(pc),a1
		move.l	_CIAABase(pc),a6
		jsr	_LVOAddICRVector(a6)
		tst.l	d0
		bne.b	.err
		move.w	#1,timerallocflag

		lea	$bfe001,a5		;inita timer
		move.b	#0,ciatalo(a5)
		move.b	#$e,ciatahi(a5)
		move.b	#%00010001,ciacra(a5)

		moveq	#0,d0
		bra.b	.end

.err		moveq	#-1,d0
.end
		movem.l	(sp)+,a5-a6
		rts


freetimer	tst.w	timerallocflag
		beq.b	.notimer

		move.l	a6,-(sp)
		moveq	#CIAICRB_TA,d0		;bort med ciaint
		lea	ciaint(pc),a1
		move.l	_CIAABase(pc),a6
		jsr	_LVORemICRVector(a6)
		clr.w	timerallocflag
		move.l	(sp)+,a6

.notimer	rts


timerallocflag	dc.w	0
timerstatus	dc.w	0

;==========================================================================
;Macros for I2C-code

I2CClk_hi	MACRO
		bset	#0,L3_I2CSTATE(a0)
		move.b	L3_I2CSTATE(a0),CREG2(a2)
		bsr.w	wait20us
		ENDM

I2CClk_lo	MACRO
		bclr	#0,L3_I2CSTATE(a0)
		move.b	L3_I2CSTATE(a0),CREG2(a2)
		bsr.w	wait20us
		ENDM

I2CData_hi	MACRO
		bset	#1,L3_I2CSTATE(a0)
		move.b	L3_I2CSTATE(a0),CREG2(a2)
		ENDM

I2CData_lo	MACRO
		bclr	#1,L3_I2CSTATE(a0)
		move.b	L3_I2CSTATE(a0),CREG2(a2)
		ENDM

I2CDataIn	MACRO
		move.b	CREG2(a2),d0
		and.b	#$4,d0
		ENDM

;========================================================================
;---l3setvol---
;d0=volume
;a0=unit
;========================================================================
l3setvol	movem.l	a2/a6,-(sp)
		move.l	_SysBase(pc),a6
		jsr	_LVODisable(a6)
		move.l	L3_BASEADR(a0),a2

		move.b	d0,.cmd+3
		bsr.w	I2CStart

		lea	.cmd(pc),a1
		moveq	#3,d1

.loop		move.b	(a1)+,d0
		bsr.w	I2COut
		tst.b	d0
		bne.b	.error
		dbf	d1,.loop

		bsr.w	I2CStop

		moveq	#0,d0
.end		move.l	_SysBase(pc),a6
		jsr	_LVOEnable(a6)
		movem.l	(sp)+,a2/a6
		rts

.error		bsr.w	I2CStop

		moveq	#-1,d0
		bra.b	.end
		rts

.cmd		dc.b	$78,$68,$40,0

;========================================================================
;---L3LoadCodec---
;a0=unit
;a1=data
;d0=size
;========================================================================
L3LoadCodec	movem.l	d7/a2,-(sp)
		move.l	L3_BASEADR(a0),a2

		move.l	d0,d7
		bsr.w	I2CStart

		move.b	#$78,d0		;address device on I2C Bus
		bsr.w	I2COut
		move.b	#$68,d0
		bsr.w	I2COut

.dl_loop	move.b	(a1)+,d0
		bsr.w	I2COut
		bsr.w	wait20us
		tst.b	d0
		bne.b	.error
		sub.l	#1,d7
		bne.b	.dl_loop

.end		bsr.w	I2CStop
		moveq	#0,d0

.exit		movem.l	(sp)+,d7/a2
		rts

.error		bsr.w	I2CStop
		moveq	#-1,d0
		bra.b	.exit

;========================================================================
;---I2COut---
;d0=data
;a2=IOBase
;========================================================================
I2COut		move.l	d7,-(sp)
			I2CClk_lo
		moveq	#7,d7
.loop
		btst	#7,d0
		beq.b	.noll
			I2CData_hi
		bra.b	.cont
.noll			I2CData_lo
.cont
		bsr.w	wait20us
			I2CClk_hi
			I2CClk_lo
		rol.b	#1,d0

		dbf	d7,.loop

			I2CData_hi	;dont drive line
		bsr.w	wait20us
			I2CClk_hi

			I2CDataIn	;slave must pull down line
		tst.b	d0
		beq.b	.ok


			I2CClk_lo	;ACK Clk
		moveq	#-1,d0		;error
		move.l	(sp)+,d7
		rts


.ok			I2CClk_lo	;ACK Clk
		moveq	#0,d0		;ok!
		move.l	(sp)+,d7
		rts


;========================================================================
;---I2CStart---
;a2=IOBase
;========================================================================
I2CStart		I2CData_hi
			I2CClk_hi
			I2CData_lo
		bsr.w	wait20us
		rts

;========================================================================
;---I2CStop---
;a2=IOBase
;========================================================================
I2CStop		bsr.w	wait20us
			I2CData_lo
			I2CClk_hi
		bsr.w	wait20us
			I2CData_hi
		rts


wait20us:	rept 28
		btst	#6,$bfe001
		endr
		rts


l3_l2codec	include	l3/layer2.i
l3_l2codecend

;========================================================================
_CIAABase	dc.l	0
ggbase		dc.l	0
unitdata	blk.b	UNITS*TRUESOUND_SIZEOF

ciaaname	dc.b	"ciaa.resource",0
endofcode
