;*************************************************************************
;** mmu.library                                                         **
;**                                                                     **
;** a system library for arbitration and control of the MC68K MMUs      **
;**                                                                     **
;** © 1998 THOR-Software, Thomas Richter                                **
;** No commercial use, reassembly, modification without prior, written  **
;** permission of the authors.                                          **
;** Including this library in any commercial software REQUIRES a        **
;** written permission and the payment of a small fee.                  **
;**                                                                     **
;** This is an internal header file, do not depend on anything here.    **
;** Use the official include files.                                     **
;** Distributed only for the mmu.library development group for private  **
;** use.                                                                **
;**                                                                     **
;**---------------------------------------------------------------------**
;** Block: Detect.a                                                     **
;** Detect a possible MMU, return the type in d0                        **
;*************************************************************************

;FOLD Includes
        include INC:exec_lib.asm
        include mu_lib.i
;ENDFOLD
;FOLD Defines
;I'm again too lazy to include the complete exec/execbase.i.
;Here just what I need:
AttnFlags       =       $128

AF_68010        =       0
AF_68020        =       1
AF_68030        =       2
AF_68040        =       3
AF_68060        =       7
;ENDFOLD

        section main_code,code

;FOLD DetectMMUType
;*************************************************
;** DetectMMUType                               **
;** Return the type of the MMU installed        **
;** this does NOT YET check whether an EC type  **
;** processor is installed, this must be done   **
;** manually afterwards. It checks only the     **
;** possible type of the MMU                    **
;*************************************************
        xdef DetectMMUType
DetectMMUType:
        saveregs a5/a6

        move.l mulib_SysBase(a6),a6
        moveq #mutype_68060,d0                  ;get the MMU type
        move.w AttnFlags(a6),d1                 ;get CPU type

        btst #AF_68060,d1
        bne.s .found

        moveq #mutype_68040,d0
        btst #AF_68040,d1
        bne.s .found

        moveq #mutype_none,d0
        btst #AF_68020,d1                       ;not even a '020?
        beq.s .found                            ;if so, exit

                                                ;check here whether MMU is available
        lea Check020MMU(pc),a5
        jsr Supervisor(a6)                      ;run the MMU checker
        tst.l d0                                ;what is it?
        beq.s .found                            ;nothing ?

        moveq #mutype_68030,d0
        move.w AttnFlags(a6),d1                 ;restore AttnFlags
        btst #AF_68030,d1                       ;is the '030 installed ?
        bne.s .found

        moveq #mutype_68020,d0
.found:
        loadregs
        rts
;ENDFOLD
;FOLD Check020MMU
;*************************************************
;** Check020MMU                                 **
;** Check, whether a 68851 is on board          **
;*************************************************

        machine mc68020
        pmmu

Check020MMU:
        ori.w #$0700,sr                 ;disable interrupts
        lea -$30(a7),a7                 ;reserve room for termporary
                                        ;exception vectors
        movec.l vbr,a0                  ;saveback VBR
        lea _IllegalEntry(pc),a1        ;entry for Illegal/LineF
        move.l a1,$10(a7)               ;set it
        move.l a1,$2c(a7)               ;ditto
        movec.l a7,vbr                  ;VBR temporary on stack
        moveq #1,d0                     ;default result is: YES
        pmove tc,(a7)                   ;try to read translation control
_Continue:
        movec.l a0,vbr                  ;restore VBR
                                        ;result is in d0
        lea $30(a7),a7                  ;release stack
        rte                             ;this restores interrupts anyways
_IllegalEntry:
        moveq #0,d0
        addq.l #8,a7                    ;remove exception stack frame
        bra.s _Continue
;ENDFOLD

