;*************************************************************************
;** 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: 68060 specific routines                                      **
;** Version 0.02                19.09.1998      © THOR                  **
;*************************************************************************

;FOLD Includes
        include mu_lib.i
        include mu_context.i
        include mu_alerts.i
;ENDFOLD
;FOLD External references
        xref SubSuper
        xref Parse060
        xref MUAlert
        xref AddTransparentTranslation
;ENDFOLD

        section main_code,code

        machine mc68060

;FOLD Init060
;*************************************************
;** Init060                                     **
;** Initialize internal vectors of the library  **
;** base for the use of the 68060 MMU           **
;**                                             **
;** *a1 = vectors to be filled out              **
;** *a6 = library base                          **
;** returns success/failure in d0               **
;*************************************************
        xdef Init060
Init060:
        lea ReadConfig(pc),a0
        move.l a0,2+mulib_ReadConfig(a6)        ;no need to flush the cache, that's done by the library anyways
        lea WriteConfig(pc),a0
        move.l a0,2+mulib_WriteConfig(a6)
        lea SetLibrary(pc),a0
        move.l a0,2+mulib_SetLibrary(a6)
        lea Parse060(pc),a0
        move.l a0,2+mulib_ParseMMU(a6)
        lea ParseTT(pc),a0
        move.l a0,2+mulib_ParseTT(a6)
        moveq #1,d0
        rts
;ENDFOLD
;FOLD ReadConfig
;*************************************************
;** ReadConfig                                  **
;** Read the MMU configuration                  **
;** to *a0 struct MMUConfig                     **
;*************************************************
ReadConfig:
        pea _ReadConfig(pc)
        bsr SubSuper
        rts
_ReadConfig:
        moveq #0,d0
        movec tc,d0                             ;read the translation control
        move.l d0,mcf_translationctrl(a0)       ;keep it
        tst.w d0
        bpl.s .disabled                         ;if disabled, ignore it
        movec.l urp,d0
        movec.l srp,d1
        clr.b d0
        clr.b d1                                ;avoid trouble and clear unused bits
        bclr #8,d0
        bclr #8,d1
        move.l d0,mcf_userrootpointer(a0)
        move.l d1,mcf_superrootpointer(a0)
.disabled:
        movec.l dtt0,d0
        movec.l dtt1,d1
        movem.l d0-d1,mcf_dtt0(a0)
        movec.l itt0,d0
        movec.l itt1,d1
        movem.l d0-d1,mcf_itt0(a0)              ;keep the translation registers
        rte
;ENDFOLD
;FOLD WriteConfig
;*************************************************
;** WriteConfig                                 **
;** install the MMU configuration in *a0        **
;*************************************************
WriteConfig:
        pea _WriteConfig(pc)
        bsr SubSuper
        rts
_WriteConfig:
        ori.w #$0700,sr                         ;all interrupts off
                                                ;here: enable it
        cpusha bc                               ;flush the caches, write back
        moveq #0,d1
        movec.l d1,tc
        movec.l d1,itt0
        movec.l d1,itt1
        movec.l d1,dtt0
        movec.l d1,dtt1                         ;clear this mess

        tst.w 2+mcf_translationctrl(a0)         ;MMU disabled ?
        bpl.s .disableme
        move.l mcf_userrootpointer(a0),d0
        move.l mcf_superrootpointer(a0),d1
        movec.l d0,urp
        movec.l d1,srp                          ;set the URP and SRP
        pflusha                                 ;flush the ATC
        move.l mcf_translationctrl(a0),d0
        movec d0,tc
.disableme:
        tst.w 2+mcf_dtt0(a0)                    ;enabled ?
        bpl.s .isdisabled0
        move.l mcf_dtt0(a0),d0
        movec.l d0,dtt0
.isdisabled0:
        tst.w 2+mcf_dtt1(a0)
        bpl.s .isdisabled1
        move.l mcf_dtt1(a0),d0
        movec.l d0,dtt1
.isdisabled1:
        tst.w 2+mcf_itt0(a0)                    ;enabled ?
        bpl.s .isdisabledi0
        move.l mcf_itt0(a0),d0
        movec.l d0,itt0
.isdisabledi0:
        tst.w 2+mcf_itt1(a0)
        bpl.s .isdisabledi1
        move.l mcf_itt1(a0),d0
        movec.l d0,itt1
.isdisabledi1:
        cpusha bc                               ;again!

        rte
;ENDFOLD
;FOLD SetLibrary
;*************************************************
;** SetLibrary                                  **
;** set the data in the library base from       **
;** the MMUConfig *a0                           **
;*************************************************
SetLibrary:
        move.w 2+mcf_translationctrl(a0),d0     ;get TC
        bpl.s .disabled                         ;is it enabled ?
                                                ;here yes: Read the values and life with them
        btst #14,d0                             ;which page size ?
        beq.s .fourKpages                       ;if clear, pages are 4K large
        move.b #13,mulib_PageBits(a6)           ;8K pages
        move.b #5,mulib_LevelCBits(a6)          ;5 Bits in the page index
        move.l #$2000,d0                        ;Pages must be on 8K boundaries
        bra.s .setremaining
.fourKpages:                                    ;default: 4K
.disabled:
        move.b #12,mulib_PageBits(a6)           ;4K pages
        move.b #6,mulib_LevelCBits(a6)          ;Level C Bits
        move.l #$1000,d0                        ;Pages must be on 4K boundaries
.setremaining:
        move.l d0,mulib_PageAlign(a6)           ;this is the page size, too
        subq.l #1,d0
        not.l d0
        move.l d0,mulib_PageMask(a6)
        move.b #7,mulib_LevelABits(a6)          ;this is fixed.
        move.b #7,mulib_LevelBBits(a6)
        move.l #$0200,d0
        clr.b mulib_InitialShift(a6)            ;no initial shift
        move.l d0,mulib_LevelAAlign(a6)
        move.l d0,mulib_LevelBAlign(a6)
        move.l d0,mulib_LevelCAlign(a6)         ;even though more bits should be available, the '060 differs here from the '040
        subq.l #1,d0
        not.l d0
        clr.b mulib_LevelDBits(a6)              ;no level D
        move.l d0,mulib_LevelAMask(a6)
        move.l d0,mulib_LevelBMask(a6)
        move.l d0,mulib_LevelCMask(a6)
        move.l #~3,mulib_IndirectMask(a6)

        clr.l mulib_UpperEnd(a6)                ;the MMU maps
        rts
;ENDFOLD
;FOLD ParseTT
;*************************************************
;** ParseTT                                     **
;** Add the modifications made thru the         **
;** transparent translation registers           **
;** *a1=MMUConfig                               **
;** *a0=Context                                 **
;*************************************************
ParseTT:
        move.l mcf_dtt0(a1),d0
        bsr _ParseTT
        beq.s .exit
        move.l mcf_dtt1(a1),d0
        bsr _ParseTT
        beq.s .exit
        move.l mcf_itt0(a1),d0
        bsr _ParseTT
        beq.s .exit
        move.l mcf_itt1(a1),d0
        bsr _ParseTT
.exit:
        rts

_ParseTT:
        movem.l a0-a1,-(a7)

        tst.w d0
        bpl.s .disabled                         ;TC is disabled, ingore

        move.l #(1<<mapp_translated),d1         ;do not touch this region
        swap d0
        move.l d0,a1

        move.l d1,d0
        bsr AddTransparentTranslation
        bra.s .exit
.disabled:
        moveq #1,d0
.exit:
        movem.l (a7)+,a0-a1
        rts
;ENDFOLD


