**
** ppc.library emulation
** (c)1998-2001 Frank Wille <frank@phoenix.owl.de>
**
** Cache functions
**
** V0.5d (27.03.1999) phx
**       PPCCacheInvalidE() and PPCCacheTrashE(). Fixed some bugs
**       from the original ppc.library.
** V0.5  (23.01.1999) phx
**       created, PPCCacheClearE().
**
	mc68040

	include	"ppclibemu.i"

        ifnd    EXEC_EXECBASE_I
        include "exec/execbase.i"
        endc


_LVOSupervisor	equ	-30


	section	CODE,code


	LIBFUNC	_PPCCacheClearE
; Flush 040/060 caches with extened control
; a0 = address
; d0 = length
; d1 = caches
	movem.l	a5-a6,-(sp)
	move.l	ppclib_SysBase(a6),a6
	lea	CacheClearE(pc),a5
	jsr	_LVOSupervisor(a6)
	movem.l	(sp)+,a5-a6
	rts

	cnop	0,4
CacheClearE:
	btst	#CACRB_ClearI,d1
	beq	1$
	cpusha	ic
1$:	btst	#CACRB_ClearD,d1
	beq	3$
	cmp.l	#$10000,d0
	bhi	4$
	move.l	a0,d1
	move.l	a0,a1
	and.w	#$f000,d1
	add.l	d0,a1
	add.w	#$fff,a1
	move.l	a1,d0
	and.w	#$f000,d0
	sub.l	d1,d0
	move.l	d1,a0
	move.l	#$1000,d1
2$:	cpushp	dc,(a0)
	add.l	d1,a0
	sub.l	d1,d0
	bgt	2$
3$:	rte
4$:	cpusha	dc
	rte


	LIBFUNC	_PPCCacheInvalidE
; Invalidate 040/060 caches with extened control
; a0 = address
; d0 = length
; d1 = caches
	movem.l	a5-a6,-(sp)
	move.l	ppclib_SysBase(a6),a6
	lea	CacheInvalidE(pc),a5
	jsr	_LVOSupervisor(a6)
	movem.l	(sp)+,a5-a6
	rts

	cnop	0,4
CacheInvalidE:
	btst	#CACRB_ClearI,d1
	beq	1$
	cinva	ic
1$:	btst	#CACRB_ClearD,d1
	beq	9$
	move.l	d2,-(sp)
	move.l	a0,d1
	move.l	#$1000,d2
	and.w	#$0fff,d1
	beq	4$
	sub.w	d1,d2
	moveq	#16,d1
	cmp.l	d2,d0
	bhs	2$
	move.l	d0,d2
2$:	sub.l	d2,d0
3$:	cmp.l	d1,d2
	blo	4$
	cinvl	dc,(a0)
	add.l	d1,a0
	sub.l	d1,d2
	bra	3$
4$:	move.l	#$1000,d2
5$:	cmp.l	d2,d0
	blo	6$
	cinvp	dc,(a0)
	add.l	d2,a0
	sub.l	d2,d0
	bra	5$
6$:	tst.w	d0
	beq	8$
	moveq	#16,d1
7$:	cmp.l	d1,d0
	blo	8$
	cinvl	dc,(a0)
	add.l	d1,a0
	sub.l	d1,d0
	bra	7$
8$:	move.l	(sp)+,d2
9$:	rte


	LIBFUNC	_PPCCacheTrashE
; Trash 040/060 caches with extened control
; a0 = address
; d0 = length
; d1 = caches
	movem.l	a5-a6,-(sp)
	move.l	ppclib_SysBase(a6),a6
	lea	CacheTrashE(pc),a5
	jsr	_LVOSupervisor(a6)
	movem.l	(sp)+,a5-a6
	rts

	cnop	0,4
CacheTrashE:
	btst	#CACRB_ClearI,d1
	beq	1$
	cinva	ic
1$:	btst	#CACRB_ClearD,d1
	beq	9$
	movem.l	d2-d3,-(sp)
	cmp.l	#$800,d0
	bhi	10$
	moveq	#16,d1
	move.l	a0,d2
	and.w	#$000f,d2
	beq	2$
	cpushl	dc,(a0)
	sub.l	d1,d2
	neg.l	d2
	add.l	d2,a0
	sub.l	d2,d0
2$:	cmp.l	d1,d0
	blo	3$
	cinvl	dc,(a0)
	add.l	d1,a0
	sub.l	d1,d0
	bra	2$
3$:	beq	4$
	cpushl	dc,(a0)
4$:	movem.l	(sp)+,d2-d3
9$:	rte

	cnop	0,4
10$:	move.l	a0,d1
	and.w	#$0fff,d1
	beq	20$
	cmp.l	#$2000,d0
	bhs	24$
	move.l	a0,d2
	lea	(a0,d0.l),a1
	and.w	#$f000,d2
	move.l	a1,d3
	and.w	#$f000,d3
	cpushp	dc,(a0)
	cmp.w	d2,d3
	beq	11$
	cpushp	dc,(a1)
11$:	movem.l	(sp)+,d2-d3
	rte

	cnop	0,4
20$:	cmp.l	#$10000,d0
	bhs	24$
	move.l	#$1000,d1
21$:	cmp.l	d1,d0
	blo	22$
	cinvp	dc,(a0)
	add.l	d1,a0
	sub.l	d1,d0
	bra	21$
22$:	beq	23$
	cpushp	dc,(a0)
23$:	movem.l	(sp)+,d2-d3
	rte

	cnop	0,4
24$:	cpusha	dc,(a0)
	movem.l	(sp)+,d2-d3
	rte
