home *** CD-ROM | disk | FTP | other *** search
- ;======================================================================
- ;
- ; 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"
-
- include "exec/types.i"
- include "exec/execbase.i"
- include "exec/tasks.i"
-
- CALLSYS macro *
- jsr LVO\1(A6)
- endm
-
- MOVEC_ macro *
- ifc '\1','cacr'
- ifc '\2','d0'
- dc.w $4e7a ; MOVEC cacr,d0
- dc.w $0002
- mexit
- endc
- ifc '\2','d1'
- dc.w $4e7a ; MOVEC cacr,d1
- dc.w $1002
- mexit
- endc
- endc
- ifc '\2','cacr'
- ifc '\1','d0'
- dc.w $4e7b ; MOVEC d0,cacr
- dc.w $0002
- mexit
- endc
- ifc '\1','d1'
- dc.w $4e7b ; MOVEC d1,cacr
- dc.w $1002
- mexit
- endc
- endc
- ifc '\1','vbr'
- ifc '\2','d0'
- dc.w $4e7a ; MOVEC vbr,d0
- dc.w $0801
- mexit
- endc
- endm
-
- PMOVE_ macro *
- ifc '\1','tc'
- ifc '\2','(sp)'
- dc.w $f017 ; PMOVE tc,(sp)
- dc.w $4200
- mexit
- endc
- ifc '\2','(a0)'
- dc.w $f010 ; PMOVE tc,(a0)
- dc.w $4200
- mexit
- endc
- endc
- ifc '\1','crp'
- ifc '\2','(a0)'
- dc.w $f010 ; PMOVE crp,(a0)
- dc.w $4e00
- mexit
- endc
- endc
- ifc '\1','(a0)'
- ifc '\2','crp'
- dc.w $f010 ; PMOVE (a0),crp
- dc.w $4c00
- mexit
- endc
- ifc '\2','tc'
- dc.w $f010 ; PMOVE (a0),tc
- dc.w $4000
- mexit
- endc
- endc
- ifc '\1','(a1)'
- ifc '\2','crp'
- dc.w $f011 ; PMOVE (a1),crp
- dc.w $4c00
- mexit
- endc
- endc
- endm
-
- CIB_ENABLE EQU 0
- CIB_FREEZE EQU 1
- CIB_ENTRY EQU 2
- CIB_CLEAR EQU 3
- CIB_BURST EQU 4
-
- CDB_ENABLE EQU 8
- CDB_FREEZE EQU 9
- CDB_ENTRY EQU 10
- CDB_CLEAR EQU 11
- CDB_BURST EQU 12
- CDB_WALLOC EQU 13
-
- CIB_ENABLE40 EQU 15
- CDB_ENABLE40 EQU 31
-
- ;AFB_68030 EQU 2
- ;AFB_68040 EQU 3
- ;AFB_68882 EQU 5
-
- ATNFLGS EQU $129
-
- LVOSupervisor EQU -30
- LVOSuperState EQU -150
- LVOFindTask EQU -294
- LVOAllocTrap EQU -342
- LVOFreeTrap EQU -348
- LVOCacheClearU EQU -636
- LVOCacheControl EQU -648
-
- ANYCREG EQU $00dff010
-
- machine mc68020
- mc68881
-
-
- 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
-
-