; mmu handling code
; last update 13/12/2003

ProtectMem:
    tst.l opt5
     beq.w ProtectMemExit
     jsr _LVOForbid(a6)
    lea MuForceName,a1
     jsr _LVOFindTask(a6)
    tst.l d0
    beq.b .NoMuForce
    move.b #1,MuForce
.NoMuForce:
     jsr _LVOPermit(a6)
    movea.l mmubase,a6
     jsr _LVOLockContextList(a6)
    movea.l dctx,a0
     jsr _LVOLockMMUContext(a6)
    movea.l sctx,a0
     jsr _LVOLockMMUContext(a6)
    movea.l dctx,a0
     jsr _LVOGetMapping(a6)
    move.l #mmufailstr4,errorbuf
    move.l d0,dctxl
     beq.w muexit1
    movea.l sctx,a0
     jsr _LVOGetMapping(a6)
    move.l #mmufailstr5,errorbuf
    move.l d0,sctxl
     beq.w muexit2
    movea.l dctx,a0
    tst.b MuForce
     beq.b .NoAggressive
    move.l #MAPP_WRITEPROTECTED|MAPP_REPAIRABLE,d1
     bra.b .continue
.NoAggressive:
    move.l #MAPP_ROM,d1
.continue:
    move.l #MAPP_WRITEPROTECTED|MAPP_ROM|MAPP_REPAIRABLE,d2
    movea.l MemForPatch,a1
    move.l mmusize,d0
    movea.w #NULL,a2
     jsr _LVOSetPropertiesA(a6)
    move.l #mmufailstr6,errorbuf
    tst.b d0
     beq.b muexit3
    movea.l sctx,a0
    tst.b MuForce
     beq.b .NoAggressive2
    move.l #MAPP_WRITEPROTECTED|MAPP_REPAIRABLE,d1
     bra.b .continue2
.NoAggressive2:
    move.l #MAPP_ROM,d1
.continue2:
    move.l #MAPP_WRITEPROTECTED|MAPP_ROM|MAPP_REPAIRABLE,d2
    movea.l MemForPatch,a1
    move.l mmusize,d0
    movea.w #NULL,a2
     jsr _LVOSetPropertiesA(a6)
    move.l #mmufailstr7,errorbuf
    tst.b d0
     beq.b muexit3
    lea dctx,a0
     jsr _LVORebuildTreesA(a6)
    move.l #mmufailstr8,errorbuf
    tst.b d0 
     beq.b undoMMUtree
    clr.b MMUError      ; if everything ok clear MMUError variable
muexit3:
    movea.l sctx,a0
    movea.l sctxl,a1
     jsr _LVOReleaseMapping(a6)
muexit2:
    movea.l dctx,a0
    movea.l dctxl,a1
     jsr _LVOReleaseMapping(a6)
muexit1:
    movea.l sctx,a0
     jsr _LVOUnlockMMUContext(a6)
    movea.l dctx,a0
     jsr _LVOUnlockMMUContext(a6)
     jsr _LVOUnlockContextList(a6)
    tst.b MMUError      ; if we arrived here with an error
     bne.w mmufailfree     ; then output an error message
    movea.l 4.w,a6
    movea.l mmubase,a1
     jsr _LVOCloseLibrary(a6)
    tst.l opt0
     bne.b ProtectMemExit
    movea.l DOSBase,a6
    move.l #MMUEnabled,d1
     jsr _LVOPutStr(a6)
    movea.l 4.w,a6
ProtectMemExit: bra.w OK   ; if we are here everything has gone
 cnop 0,4
undoMMUtree:
    movea.l dctx,a0
    movea.l dctxl,a1
     jsr _LVOSetPropertyList(a6)
    movea.l sctx,a0
    movea.l sctxl,a1
     jsr _LVOSetPropertyList(a6)
   bra.w muexit3
 cnop 0,4                       

MMUInstall: movea.l 4.w,a6      ; it opens mmu.library and checks for a MMU
    moveq.l #41,d0      ; minimum V41 required
    lea mmuname,a1
     jsr _LVOOpenLibrary(a6)
    move.l #mmufailstr1,errorbuf
    move.l d0,mmubase
     beq.w mmufail2             ; error, you don't have the mmu.library
    movea.l d0,a6
     jsr _LVOGetMMUType(a6)
    move.l #mmufailstr2,errorbuf  ; error you don't have MMU
    tst.b d0
     beq.w mmufail
     jsr _LVODefaultContext(a6)
    move.l d0,dctx
    movea.l d0,a0
     jsr _LVOSuperContext(a6)
    move.l d0,sctx
    movea.l dctx,a0
     jsr _LVOGetPageSize(a6)
    move.l d0,psize
.AllocMem: move.l #MEMF_PUBLIC|MEMF_FAST|MEMF_CLEAR,d1
    move.l #EndPatch-StartPatch,d0
    move.l psize,d4
    subq.l #1,d4     ; d4 contains page mask
    add.l d4,d0         ; add pagemask for adress aligning
    add.l d4,d0         ; add pagemask for space aligning
    move.l d0,OrigAllocSize
    movea.l 4.w,a6
     jsr _LVOAllocMem(a6)
    move.l #mmufailstr3,errorbuf
    move.l d0,OrigAllocMem
     beq.b mmufail
    add.l d4,d0
    move.l d0,d2
    and.l d4,d2
    sub.l d2,d0         ; aligns address to pagemask boundaries
.calcsize:
    move.l d0,MemForPatch
    move.l #EndPatch-StartPatch,d0
    add.l d4,d0
    move.l d0,d2
    and.l d4,d2
    sub.l d2,d0         ; aligns space to pagemask boundaries
.fatto:
    move.l d0,mmusize
    movea.l MemForPatch,a1
   bra.w cp2
 cnop 0,4
mmufailfree: movea.l 4.w,a6
    movea.l OrigAllocMem,a1
    move.l OrigAllocSize,d0
     jsr _LVOFreeMem(a6)
mmufail: movea.l 4.w,a6
    movea.l mmubase,a1
     jsr _LVOCloseLibrary(a6)
mmufail2: bra.b MMUF
