
*******************************************************************************
* GetCPU
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
*	This routine will allow us to determine the type of CPU installed in
* the host. Trying any 68010/020/030 instructions will cause either an Illegal 
* Instruction or a 1111 Opcode error exception if the respective parts aren't
* present. e.g if the CPU is a 68000, so we set up trap to cater for this.
*
* INPUTS ;	None.
* OUTPUTS;	d0=AFB Bits... se below for there meanings...
*******************************************************************************
AFB_68010	=	0			;bit to set if MC68010
AFB_68020	=	1			;bit to set if MC68020
AFB_68030	=	2			;bit to set if MC68030
AFB_68040	=	3			;bit to set if MC68040

AFB_68881	=	4			;bit to set if a maths 68881
AFB_68882	=	5			;bit to set if a maths 68882

;
CACR_ON		=	1			;instruction cache on
CACR_OFF	=	0			;instruction cache off

GetCPU:		movem.l	a2/a3,-(sp)		;preserve regs
		move.l	$10.w,a0		;'Illegal instruction' vector
		move.l	$2c.w,a2		;'1111 Opcode' error vector

		lea	CPUHandler(pc),a1	;set up a new temp handler
		move.l	a1,$10.w		;Temp 'Illegal Instruction'
		move.l	a1,$2c.w		;Temp '1111 Opcode'
		move.l	sp,a1			;save the stack pointer

;	Initialize the flags to zero (D0), and point to address zero (D1).
; Then we try to set the 68010 Vector Base Register, which determines where the
; exception vector table is.  In the 68000, this is hardwired at zero.  If the
; 68010 is present, we set it to zero. If the VBR was not at 0 then a0 and a1
; will contain garbage... they will not contain the 'Illegal Instruction' or
; 1111 Opcode' vector addresses.

		moveq	#0,d0			;clear d1 (VBR_ADDRESS)
		movec	D0,VBR			;Vector Base Register to 0.

;	If we're still here, the CPU is at least a 68010.  We thus set
; the AFB_68010 flag.  Then we try to access a 68020-specific feature, namely,
; we try to enable its INSTRUCTION CACHE.

		moveq	#0,d0			;clear d0 (AFB_FLAGS)
		bset	#AFB_68010,d0		;Set AFB_68010 flag.
		moveq	#CACR_ON,d1		;try to turn it on
		movec	d1,CACR			;Try enabling the 68020 cache.

;	If we're still here, we have a 68020, and so we set the AFB_68020
; flag.  Then we see if we also have a 68881 FPCP, by trying to access one of
; its registers. Note; This will not cause an exception if no FPP is present.

		bset	#AFB_68020,d0		;Set AFB_68020 flag.

;		fmove.l	FPCR,d1			; Try reading a 68881 register.
;		tst.l	d1			; Did it work?
;		bne.s	CPUHandler
;		bset	#AFB_68881,d0		; If so,set the AFB_68881 flag.
;
; We continue here either from above, or, on plain Amigas, by an error 
; exception from one of the foreign instructions above. d0 contains all the 
; flags which have been set along the way. We restore the two changed entries 
; in the EVT and the stack pointer, then exit.

CPUHandler:	move.l	a1,sp			; Restore stack pointer.
		move.l	a0,$10.w		; Restore 'Illegal Instruction'
		move.l	a2,$2c.w		; Restore '1111 OpCode'
		movem.l	(sp)+,a2/a3		; restore trashed registers
		rts

