home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
system_utils
/
general
/
setcpu_400
/
idents.a
< prev
next >
Wrap
Text File
|
1990-11-03
|
6KB
|
229 lines
;======================================================================
;
; SetCPU V1.60
; by Dave Haynie, April 13, 1990
; Released to the Public Domain
;
; IDENTS.A MODULE
;
; This module contains the functions that ID the CPU, MMU, and FPU
; type indtalled in the system.
;
;======================================================================
include "setcpu.i"
cseg
xdef _GetCPUType ; ID the CPU
xdef _GetMMUType ; ID the MMU
xdef _GetFPUType ; ID the FPU
;======================================================================
;
; This routine checks CPU flags early in ExecBase for extended
; CPUs that test as a 68020 under 1.3. If these flags are set,
; the actual CPU/MMU type test can be skipped.
;
;======================================================================
TestFlags:
moveq.l #0,d0
btst.b #AFB_68040,ATNFLGS(a6) ; Does the OS think an '040 is here?
beq NoEarly40
move.l #68040,d0
rts
NoEarly40:
btst.b #AFB_68030,ATNFLGS(a6) ; Does the OS think an '030 is here?
beq NoEarly30
move.l #68030,d0 ; Sure does...
NoEarly30:
rts
;======================================================================
;
; This function returns the type of the CPU in the system as a
; longword: 68000, 68010, 68020, or 68030. The testing must be done
; in reverse order, in that any higher CPU also has the bits set for
; a lower CPU. Also, since 1.3 doesn't recognize the 68030, if I
; find the 68020 bit set, I always check for the presence of a
; 68030.
;
; This routine should be the first test routine called under 1.2
; and 1.3.
;
; ULONG GetCPUType();
;
;======================================================================
_GetCPUType:
move.l 4,a6 ; Get ExecBase
jsr TestFlags ; Check extended CPU types
cmp.l #0,d0
beq CPURealTest
rts
CPURealTest:
movem.l a4/a5,-(sp) ; Save this register
btst.b #AFB_68020,ATNFLGS(a6) ; Maybe a 68020
bne FindReal32
btst.b #AFB_68010,ATNFLGS(a6) ; Maybe a 68010?
bne Found10
move.l #68000,d0 ; Just a measley '000
movem.l (sp)+,a4/a5
rts
Found10:
move.l #68010,d0 ; Yup, we're an '010
movem.l (sp)+,a4/a5
rts
FindReal32:
move.w LIB_VERSION(a6),d0 ; Are we in 2.0?
cmp.w #36,d0 ; If so, we don't need to test
bge No40
lea.l SuperGCT,a5 ; Get the start of the supervisor code
CALLSYS Supervisor
btst.l #CIB_BURST,d0 ; Do we have a set burst bit?
beq No30
move.l #68030,d0 ; It's a 68030
bset.b #AFB_68030,ATNFLGS(a6)
movem.l (sp)+,a4/a5
rts
No30:
btst.l #CIB_ENABLE40,d1 ; Do we have 040 cache enable?
beq No40
move.l #68040,d0 ; It's a 68040
bset.b #AFB_68040,ATNFLGS(a6)
movem.l (sp)+,a4/a5
rts
No40:
move.l #68020,d0 ; Guess we're a plain old '020
movem.l (sp)+,a4/a5
rts
; This routine tries to set a few interesting CACR bits, and
; returns the actual register value that took in d0.
SuperGCT:
MOVEC_ cacr,d1 ; Get the cache register
move.l d1,d0 ; Make a copy
bset.l #CIB_BURST,d0 ; Set the inst burst bit 030
bclr.l #CIB_ENABLE,d0 ; Clear the inst cache bit 030
bset.l #CIB_ENABLE40,d0 ; Set the inst cache bit 040
MOVEC_ d0,cacr ; Try to set the CACR
MOVEC_ cacr,d0 ; Save the real value
MOVEC_ d1,cacr ; Restore it
rte
;======================================================================
;
; This function returns 0L if the system contains no MMU,
; 68851L if the system does contain an 68851, or the CPU number
; for CPUs with integral CPUs.
;
; This routine seems to lock up on at least some CSA 68020
; boards, though it runs just fine on those from Ronin and
; Commodore, as well as all 68030 boards it's been tested on.
;
; ULONG GetMMUType()
;
;======================================================================
_GetMMUType:
move.l 4,a6 ; Get ExecBase
jsr TestFlags ; Check extended CPU types
cmp.l #0,d0
beq MMURealTest
rts
; For any other machine, a real test must be done. The test will
; try an MMU instruction. The instruction will fail unless we're
; on a "bogus MMU" system, where the FPU responds as an MMU.
MMURealTest:
movem.l a3/a4/a5,-(sp) ; Save this stuff
move.l #0,a1
CALLSYS FindTask ; Call FindTask(0L)
move.l d0,a3
move.l TC_TRAPCODE(a3),a4 ; Change the exception vector
move.l #MMUTraps,TC_TRAPCODE(a3)
move.l #-1,d0 ; Try to detect undecode FPU
subq.l #4,sp ; Get a local variable
PMOVE_ tc,(sp) ; Let's try an MMU instruction
addq.l #4,sp ; Return that local
move.l a4,TC_TRAPCODE(a3) ; Reset exception stuff
movem.l (sp)+,a3/a4/a5 ; and return the registers
rts
; This is the exception code. No matter what machine we're on,
; we get an exception. If the MMU's in place, we should get a
; privilige violation; if not, an F-Line emulation exception.
MMUTraps:
move.l (sp)+,d0 ; Get Amiga supplied exception #
cmpi #11,d0 ; Is it an F-Line?
beq MMUNope ; If so, go to the fail routine
move.l #68851,d0 ; We have MMU
addq.l #4,2(sp) ; Skip the MMU instruction
rte
MMUNope:
moveq.l #0,d0 ; It dinna woik,
addq.l #4,2(sp) ; Skip the MMU instruction
rte
;======================================================================
;
; This function returns the type of the FPU in the system as a
; longword: 0 (no FPU), 68881, or 68882.
;
; ULONG GetFPUType();
;
;======================================================================
_GetFPUType:
move.l 4,a6 ; Get ExecBase
btst.b #AFB_68040,ATNFLGS(a6) ; Is there a 68040 here?
beq Look4FPU
move.l #68040,d0
rts
Look4FPU:
move.l a5,-(sp) ; Save this register
btst.b #AFB_68881,ATNFLGS(a6) ; Does the OS think an FPU is here?
bne FPUHere
moveq.l #0,d0 ; No FPU here, dude
move.l (sp)+,a5 ; Give back the register
rts
FPUHere:
btst.b #AFB_68882,ATNFLGS(a6) ; How's about an '882?
beq FPUTest
move.l #68882,d0 ; Sure does...
move.l (sp)+,a5
rts
FPUTest:
move.w LIB_VERSION(a6),d0 ; Are we in 2.0?
cmp.w #36,d0 ; If so, we don't need to test
blt FPUTrap
move.l #68881,d0
move.l (sp)+,a5
rts
FPUTrap:
lea.l FPUSuper,a5 ; Get the start of the supervisor code
CALLSYS Supervisor
move.l (sp)+,a5 ; Give back registers
rts
FPUSuper:
move.l #68881,d0 ; Assume we're a 68881
fsave -(sp) ; Test and check
moveq.l #0,d1
move.b 1(sp),d1 ; Size of this frame
cmpi #$18,d1
beq FPU81
move.l #68882,d0 ; It's a 68882
bset.b #AFB_68882,ATNFLGS(a6)
FPU81:
frestore (sp)+ ; Restore the stack
rte
end