;======================================================================
;
;	SetCPU V1.60
;	by Dave Haynie, April 13, 1990
;	Released to the Public Domain
;
;	CONTROL.A MODULE
;
;	This module contains functions that access various control
;	registers in the 32 bit CPUs and MMUs.
;
;======================================================================

	include "setcpu.i"

	cseg

;**********************************************************************
;
;	These functions work with the CPU control registers.
;
**********************************************************************

	xdef	_SetCACR	; Set CACR register
	xdef	_GetCACR	; Get CACR register
	xdef	_GetVBR		; Get the Vector Base Register

;======================================================================
;
;	This function sets the value of the 68020/68030 CACR register.  
;	It assumes a 68020 or 68030 based system.
;
;	void SetCACR(cacr)
;	ULONG cacr;
;
;======================================================================

_SetCACR:
	move.l	4(sp),d0		; New CACR is on stack
 	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)		; Save this register
	lea.l	1$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	move.l	(sp)+,a5		; Give it back
	rts
1$
	MOVEC_	d0,cacr			; Set the CACR
	rte

;======================================================================
;
;	This function returns the 68020/68030 CACR register.  It assumes
;	a 68020 or better system.
;
;	ULONG GetCACR()
;
;======================================================================

_GetCACR:
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)		; Save this register
	lea.l	1$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	move.l	(sp)+,a5		; Give back register
	rts
1$
	MOVEC_	cacr,d0			; Make CACR the return value
	rte

;======================================================================
;
;	This function returns the value of the Vector Base Register;
;	all exceptions are referenced from this.  This function assumes
;	we're on a CPU with a VBR (eg, no 68000's need apply).
;
;	ULONG *GetVBR()
;
;======================================================================

_GetVBR:
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)		; Save this register
	lea.l	1$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	move.l	(sp)+,a5		; Give back register
	rts
1$
	MOVEC_	vbr,d0			; Make CACR the return value
	rte

;**********************************************************************
;
;	These functions access MMU registers
;
;**********************************************************************

	xdef	_GetCRP		; Gets MMU CRP register
	xdef	_SetCRP		; Sets MMU CRP register
	xdef	_GetTC		; Gets MMU TC register
	xdef	_SetTC		; Gets MMU TC register

;======================================================================
;
;	This function returns the MMU CRP register.  It assumes a 68020 
;	system with MMU, or a 68030 based system (eg, test for MMU before
;	you call this, or you wind up in The Guru Zone).  Note that the
;	CRP register is two longwords long.
;
;	void GetCRP(ULONG *)
;
;======================================================================

_GetCRP:
	move.l	4(sp),a0		; Pointer to the CRP storage area
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)
	lea.l	2$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	move.l	(sp)+,a5
	rts
2$
	PMOVE_	crp,(a0)		; Just get the CRP register
	rte

;======================================================================
;
;	This function sets the MMU CRP register.  It assumes a 68020 
;	system with MMU, or a 68030 based system (eg, test for MMU before
;	you call this, or you wind up in The Guru Zone).  Note that the
;	CRP register is two longwords long.
;
;	void SetCRP(ULONG *)
;
;======================================================================

_SetCRP:
	move.l	4(sp),a0		; Pointer to the CRP storage area
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)
	lea.l	1$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	movem.l	(sp)+,a5		; Give back registers
	rts
1$
	PMOVE_	(a0),crp		; Just load the CRP register
	rte

;======================================================================
;
;	This function returns the MMU TC register.  It assumes a 68020 
;	system with MMU, or a 68030 based system (eg, test for MMU before
;	you call this, or you wind up in The Guru Zone).  
;
;	ULONG GetTC()
;
;======================================================================

_GetTC:
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)
	subq.l	#4,sp			; Make a place to dump TC
	move.l	sp,a0
	lea.l	1$,a5			; Get the start of the supervisor code
	CALLSYS	Supervisor
	move.l	(sp),d0			; Here's the result
	addq.l	#4,sp
	move.l	(sp)+,a5
	rts
1$
	PMOVE_	tc,(a0)			; Just get the TC register
	rte

;======================================================================
;
;	This function sets the MMU TC register.  It assumes a 68020 
;	system with MMU, or a 68030 based system (eg, test for MMU before
;	you call this, or you wind up in The Guru Zone).  
;
;	void SetTC(ULONG)
;
;======================================================================

_SetTC:
	lea.l	4(sp),a0		; Get address of our new TC value
	move.l	4,a6			; Get ExecBase
	move.l	a5,-(sp)
	lea.l	1$,a5			; Get the start of the supervisor code
 	CALLSYS	Supervisor
	move.l	(sp)+,a5
	rts
1$
	PMOVE_	(a0),tc			; Just set the TC register
	rte

