home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / disks / disk400.lzh / SetCPU / idents.a < prev    next >
Text File  |  1990-11-03  |  6KB  |  229 lines

  1. ;======================================================================
  2. ;
  3. ;    SetCPU V1.60
  4. ;    by Dave Haynie, April 13, 1990
  5. ;    Released to the Public Domain
  6. ;
  7. ;    IDENTS.A MODULE
  8. ;
  9. ;    This module contains the functions that ID the CPU, MMU, and FPU
  10. ;    type indtalled in the system.
  11. ;
  12. ;======================================================================
  13.  
  14.     include "setcpu.i"
  15.  
  16.     cseg
  17.  
  18.     xdef    _GetCPUType    ; ID the CPU
  19.     xdef    _GetMMUType    ; ID the MMU
  20.     xdef    _GetFPUType    ; ID the FPU
  21.  
  22. ;======================================================================
  23. ;
  24. ;    This routine checks CPU flags early in ExecBase for extended
  25. ;    CPUs that test as a 68020 under 1.3.  If these flags are set,
  26. ;    the actual CPU/MMU type test can be skipped.
  27. ;
  28. ;======================================================================
  29.  
  30. TestFlags:
  31.     moveq.l    #0,d0
  32.     btst.b    #AFB_68040,ATNFLGS(a6)    ; Does the OS think an '040 is here?
  33.     beq NoEarly40
  34.     move.l    #68040,d0
  35.     rts
  36. NoEarly40:
  37.     btst.b    #AFB_68030,ATNFLGS(a6)    ; Does the OS think an '030 is here?
  38.     beq    NoEarly30
  39.     move.l    #68030,d0        ; Sure does...
  40. NoEarly30:
  41.     rts
  42.  
  43.  
  44. ;======================================================================
  45. ;
  46. ;    This function returns the type of the CPU in the system as a
  47. ;    longword: 68000, 68010, 68020, or 68030.  The testing must be done
  48. ;    in reverse order, in that any higher CPU also has the bits set for
  49. ;    a lower CPU.  Also, since 1.3 doesn't recognize the 68030, if I
  50. ;    find the 68020 bit set, I always check for the presence of a 
  51. ;    68030.
  52. ;
  53. ;    This routine should be the first test routine called under 1.2
  54. ;    and 1.3.
  55. ;
  56. ;    ULONG GetCPUType();
  57. ;
  58. ;======================================================================
  59.  
  60. _GetCPUType:
  61.     move.l    4,a6            ; Get ExecBase
  62.     jsr    TestFlags        ; Check extended CPU types
  63.     cmp.l    #0,d0
  64.     beq    CPURealTest
  65.     rts
  66. CPURealTest:
  67.     movem.l    a4/a5,-(sp)        ; Save this register
  68.     btst.b    #AFB_68020,ATNFLGS(a6)    ; Maybe a 68020
  69.     bne    FindReal32
  70.     btst.b    #AFB_68010,ATNFLGS(a6)    ; Maybe a 68010?
  71.     bne    Found10
  72.     move.l    #68000,d0        ; Just a measley '000
  73.     movem.l    (sp)+,a4/a5
  74.     rts
  75. Found10:
  76.     move.l    #68010,d0        ; Yup, we're an '010
  77.     movem.l    (sp)+,a4/a5
  78.     rts
  79. FindReal32:
  80.     move.w    LIB_VERSION(a6),d0    ; Are we in 2.0?
  81.     cmp.w    #36,d0            ; If so, we don't need to test
  82.     bge    No40
  83.  
  84.     lea.l    SuperGCT,a5        ; Get the start of the supervisor code
  85.     CALLSYS    Supervisor
  86.  
  87.     btst.l    #CIB_BURST,d0        ; Do we have a set burst bit?
  88.     beq    No30
  89.     move.l    #68030,d0        ; It's a 68030
  90.     bset.b    #AFB_68030,ATNFLGS(a6)
  91.     movem.l    (sp)+,a4/a5
  92.     rts
  93. No30:    
  94.     btst.l    #CIB_ENABLE40,d1    ; Do we have 040 cache enable?
  95.     beq    No40
  96.     move.l    #68040,d0        ; It's a 68040
  97.     bset.b    #AFB_68040,ATNFLGS(a6)
  98.     movem.l    (sp)+,a4/a5
  99.     rts
  100. No40:
  101.     move.l    #68020,d0        ; Guess we're a plain old '020
  102.     movem.l    (sp)+,a4/a5
  103.     rts
  104.  
  105.     ; This routine tries to set a few interesting CACR bits, and
  106.     ; returns the actual register value that took in d0.
  107. SuperGCT:
  108.     MOVEC_    cacr,d1            ; Get the cache register
  109.     move.l    d1,d0            ; Make a copy
  110.     bset.l    #CIB_BURST,d0        ; Set the inst burst bit 030
  111.     bclr.l    #CIB_ENABLE,d0        ; Clear the inst cache bit 030
  112.     bset.l    #CIB_ENABLE40,d0    ; Set the inst cache bit 040
  113.     MOVEC_    d0,cacr            ; Try to set the CACR
  114.     MOVEC_    cacr,d0            ; Save the real value
  115.     MOVEC_    d1,cacr            ; Restore it
  116.     rte
  117.  
  118. ;======================================================================
  119. ;
  120. ;    This function returns 0L if the system contains no MMU, 
  121. ;    68851L if the system does contain an 68851, or the CPU number
  122. ;    for CPUs with integral CPUs.
  123. ;
  124. ;    This routine seems to lock up on at least some CSA 68020 
  125. ;    boards, though it runs just fine on those from Ronin and 
  126. ;    Commodore, as well as all 68030 boards it's been tested on.
  127. ;
  128. ;    ULONG GetMMUType()
  129. ;
  130. ;======================================================================
  131.  
  132. _GetMMUType:
  133.     move.l    4,a6            ; Get ExecBase
  134.     jsr    TestFlags        ; Check extended CPU types
  135.     cmp.l    #0,d0
  136.     beq    MMURealTest
  137.     rts
  138.  
  139.     ; For any other machine, a real test must be done.  The test will
  140.     ; try an MMU instruction.  The instruction will fail unless we're
  141.     ; on a "bogus MMU" system, where the FPU responds as an MMU.
  142. MMURealTest:
  143.     movem.l    a3/a4/a5,-(sp)        ; Save this stuff
  144.     move.l    #0,a1    
  145.     CALLSYS    FindTask        ; Call FindTask(0L)
  146.     move.l    d0,a3
  147.  
  148.     move.l    TC_TRAPCODE(a3),a4    ; Change the exception vector
  149.     move.l    #MMUTraps,TC_TRAPCODE(a3)
  150.     
  151.     move.l    #-1,d0            ; Try to detect undecode FPU
  152.     subq.l    #4,sp            ; Get a local variable
  153.     PMOVE_    tc,(sp)            ; Let's try an MMU instruction
  154.     addq.l    #4,sp            ; Return that local
  155.     move.l    a4,TC_TRAPCODE(a3)    ; Reset exception stuff
  156.     movem.l    (sp)+,a3/a4/a5        ; and return the registers
  157.     rts
  158.  
  159.     ; This is the exception code.  No matter what machine we're on,
  160.     ; we get an exception.  If the MMU's in place, we should get a
  161.     ; privilige violation; if not, an F-Line emulation exception.
  162. MMUTraps:
  163.     move.l    (sp)+,d0        ; Get Amiga supplied exception #
  164.     cmpi    #11,d0            ; Is it an F-Line?
  165.     beq    MMUNope            ; If so, go to the fail routine
  166.     move.l    #68851,d0        ; We have MMU
  167.     addq.l    #4,2(sp)        ; Skip the MMU instruction
  168.     rte
  169. MMUNope:
  170.     moveq.l    #0,d0            ; It dinna woik,
  171.     addq.l    #4,2(sp)        ; Skip the MMU instruction
  172.     rte
  173.  
  174. ;======================================================================
  175. ;
  176. ;    This function returns the type of the FPU in the system as a
  177. ;    longword: 0 (no FPU), 68881, or 68882.
  178. ;
  179. ;    ULONG GetFPUType();
  180. ;
  181. ;======================================================================
  182.  
  183. _GetFPUType:
  184.     move.l    4,a6            ; Get ExecBase
  185.     btst.b    #AFB_68040,ATNFLGS(a6)    ; Is there a 68040 here?
  186.     beq    Look4FPU
  187.     move.l    #68040,d0
  188.     rts
  189. Look4FPU:    
  190.     move.l    a5,-(sp)        ; Save this register
  191.     btst.b    #AFB_68881,ATNFLGS(a6)    ; Does the OS think an FPU is here?
  192.     bne    FPUHere
  193.     moveq.l    #0,d0            ; No FPU here, dude
  194.     move.l    (sp)+,a5        ; Give back the register
  195.     rts
  196. FPUHere:
  197.     btst.b    #AFB_68882,ATNFLGS(a6)    ; How's about an '882?
  198.     beq    FPUTest
  199.     move.l    #68882,d0        ; Sure does...
  200.     move.l    (sp)+,a5
  201.     rts
  202. FPUTest:
  203.     move.w    LIB_VERSION(a6),d0    ; Are we in 2.0?
  204.     cmp.w    #36,d0            ; If so, we don't need to test
  205.     blt    FPUTrap
  206.     move.l    #68881,d0
  207.     move.l    (sp)+,a5
  208.     rts
  209. FPUTrap:
  210.     lea.l    FPUSuper,a5        ; Get the start of the supervisor code
  211.     CALLSYS    Supervisor
  212.     move.l    (sp)+,a5        ; Give back registers
  213.     rts
  214. FPUSuper:
  215.     move.l    #68881,d0        ; Assume we're a 68881
  216.     fsave    -(sp)            ; Test and check
  217.     moveq.l    #0,d1
  218.     move.b    1(sp),d1        ; Size of this frame
  219.     cmpi    #$18,d1
  220.     beq FPU81
  221.     move.l    #68882,d0        ; It's a 68882
  222.     bset.b    #AFB_68882,ATNFLGS(a6)
  223. FPU81:
  224.     frestore (sp)+            ; Restore the stack
  225.     rte
  226.  
  227.     end
  228.  
  229.