;    MMU.asm  written by Michael R. Mossman and released to 
;    Public Domain in Oct 89.


               CSECT text,0,,0,4
               INCLUDE "exec/types.i"
	       INCLUDE "exec/tasks.i"
	   
	   STRUCTURE MMUM,0
	       ULONG MMUM_LOGICAL_ADDRESS    
	       ULONG MMUM_PHYSICAL_ADDRESS
	       LABEL MMUM_SIZE

           STRUCTURE MMU,MMUM_SIZE
               ULONG MMU_UCRP
               ULONG MMU_LCRP
               ULONG MMU_USRP
               ULONG MMU_LSRP
               ULONG MMU_UDRP
               ULONG MMU_LDRP
               ULONG MMU_TC
               UWORD MMU_AC
               UWORD MMU_PSR
               UWORD MMU_PCSR
               UBYTE MMU_CAL
               UBYTE MMU_VAL
               UBYTE MMU_SCC
	       UBYTE MMU_BLANK
               LABEL MMU_SIZE

CRP_OUT        EQU   %11110000000100000100111000000000	       
SRP_OUT        EQU   %11110000000100000100101000000000
DRP_OUT        EQU   %11110000000100000100011000000000
TC_OUT         EQU   %11110000000100000100001000000000
AC_OUT         EQU   %11110000000100000101111000000000
PSR_OUT        EQU   %11110000000100000110001000000000
PCSR_OUT       EQU   %11110000000100000110011000000000
CAL_OUT        EQU   %11110000000100000101001000000000
VAL_OUT        EQU   %11110000000100000101011000000000
SCC_OUT        EQU   %11110000000100000101101000000000


CRP_IN         EQU   %11110000000100000100110000000000	       
SRP_IN         EQU   %11110000000100000100100000000000
DRP_IN         EQU   %11110000000100000100010000000000
TC_IN          EQU   %11110000000100000100000000000000
AC_IN          EQU   %11110000000100000101110000000000
PSR_IN         EQU   %11110000000100000110000000000000
PCSR_IN        EQU   %11110000000100000110010000000000
CAL_IN         EQU   %11110000000100000101000000000000
VAL_IN         EQU   %11110000000100000101010000000000
SCC_IN         EQU   %11110000000100000101100000000000

READ_TAB       EQU   %11110000000100001001111100110110

CALLSYS        macro  *
               jsr    LVO\1(A6)
	       endm
	
P_MOVE         macro  *
               CNOP  0,2
               DC.l   \1
	       CNOP  0,2
	       endm

P_TEST         macro  *
               CNOP  0,2
               DC.l   \1
	       CNOP  0,2
	       endm

	       XREF _myMMU
	       XDEF _Read_MMU
	       XDEF _Write_MMU
	       XDEF _Read_Table
	       XDEF _End
	       XDEF _MMU_PRESENT
	       XDEF _EXCEPTION


LVOSupervisor  EQU  -30
LVOFindTask    EQU  -294	       
	       
SuperVisor:
               movem.l D2-D7/A2-A6,-(SP)
               move.l 4,A6
	       jsr Test_For_MMU
               move.l ADDRESS,A5
	       CALLSYS Supervisor
	       movem.l (SP)+,D2-D7/A2-A6
	       rts


	       
_Read_MMU:
	       lea Read,A0
	       move.l A0,ADDRESS
	       jmp SuperVisor
	       
	       
Read:	       
               lea _myMMU,A1
               lea MMU_UCRP(A1),A0
	       P_MOVE CRP_OUT
	       lea MMU_USRP(A1),A0
	       P_MOVE SRP_OUT
	       lea MMU_UDRP(A1),A0
	       P_MOVE DRP_OUT
	       lea MMU_TC(A1),A0
	       P_MOVE TC_OUT
	       lea MMU_AC(A1),A0
	       P_MOVE AC_OUT
	       lea MMU_PSR(A1),A0
	       P_MOVE PSR_OUT
	       lea MMU_PCSR(A1),A0
	       P_MOVE PCSR_OUT
	       lea MMU_CAL(A1),A0
	       P_MOVE CAL_OUT
	       lea MMU_VAL(A1),A0
	       P_MOVE VAL_OUT
	       lea MMU_SCC(A1),A0
	       P_MOVE SCC_OUT
	       move.l #1,D0
	       rte
	       
	       
_Write_MMU:
              move.l 4(SP),OFFSET_ADD
              lea Write,A0
	      move.l A0,ADDRESS
	      jmp SuperVisor
	      
Write:
              lea _myMMU,A0
	      exg A0,D0
	      move.l OFFSET_ADD,D1
	      move.l D1,A0
	      sub.l D0,D1
	      cmpi #MMU_UCRP,D1
	      bne 1$
	      P_MOVE CRP_IN
	      jmp 11$
	      
1$:
              cmpi #MMU_USRP,D1
              bne 2$
	      P_MOVE SRP_IN
	      jmp 11$	      	      
	             
2$:    
              cmpi #MMU_UDRP,D1
              bne 3$
	      P_MOVE DRP_IN
	      jmp 11$
	      
	      
3$:            
              cmpi #MMU_TC,D1
	      bne 4$
	      P_MOVE TC_IN
	      jmp 11$


4$:           
              cmpi #MMU_AC,D1
              bne 5$
	      P_MOVE AC_IN
	      jmp 11$	      

5$: 
              cmpi #MMU_PSR,D1
              bne 6$
	      P_MOVE PSR_IN
	      jmp 11$

6$:
              cmpi #MMU_PCSR,D1
	      bne 7$
	      P_MOVE PCSR_IN
	      jmp 11$    

7$:
              cmpi #MMU_CAL,D1
	      bne 8$
	      P_MOVE CAL_IN
	      jmp 11$	      

8$:
              cmpi #MMU_VAL,D1
	      bne 9$
	      P_MOVE VAL_IN
	      jmp 11$


9$:
              cmpi #MMU_SCC,D1
	      bne 10$
	      P_MOVE SCC_IN
	      jmp 11$

10$:
              move.l #0,D0
              rte
	      
11$:          
              move.l #1,D0
	      rte	      	      
	      	      

_Read_Table:
              jsr _Read_MMU
	      lea _myMMU,A0
	      cmpi.l #$80000000,MMU_TC(A0)
	      bcc 1$
	      move.l #0,MMUM_PHYSICAL_ADDRESS(A0)
	      move.l #0,D0
	      rts
1$	      
	      lea Read_Table,A0
	      move.l A0,ADDRESS
	      jmp SuperVisor

Read_Table:
              lea _myMMU,A1
	      move.l MMUM_LOGICAL_ADDRESS(A1),A0
	      P_TEST READ_TAB
	      lea _myMMU,A0
	      move.l A1,MMUM_PHYSICAL_ADDRESS(A0)
	      move.l #1,D0
	      rte


Test_For_MMU:
              move.l _MMU_PRESENT,D0     ;test for MMU and turn on trapping
	      beq  1$
	      rts
	      
1$:           
              move.l 4,A6
              move.l #0,A1
	      CALLSYS FindTask
	      move.l D0,A5
	      move.l TC_TRAPCODE(A5),A4
	      move.l #3$,TC_TRAPCODE(A5)
	      lea _myMMU,A1
              lea MMU_UCRP(A1),A0
	      P_MOVE CRP_OUT
	      move.l A4,TC_TRAPCODE(A5)
	      move.l _MMU_PRESENT,D0
	      beq  2$
	      move.l $E0,CONFIG
	      move.l $E4,ILLEGAL
	      move.l $E8,ACCESS
	      lea 5$,A0
	      move.l A0,$E0
	      lea 5$,A0
	      move.l A0,$E4
	      lea 5$,A0
	      move.l A0,$E8
	      rts       

2$:          
              addq.l #4,SP
	      movem.l (SP)+,D2-D7/A2-A6
	      move.l #0,D0
	      rts
	      
3$:           
              move.l (SP)+,D0
	      cmpi #11,D0
	      beq 4$
	      move.l #1,_MMU_PRESENT
	      addq.l #4,2(SP)
	      rte
	      
4$:           
              addq.l #4,2(SP)
	      rte	      	      


5$:           
              move.l D0,-(SP)    ;trap exceptions 56-58
	      move.l #0,D0
	      move.w 10(SP),D0
	      andi.w #$0FFF,D0
	      divu.w #4,D0
	      move.w D0,_EXCEPTION
	      move.l (SP)+,D0
	      rte


_End:
              move.l CONFIG,$E0
	      move.l ILLEGAL,$E4
	      move.l ACCESS,$E8
	      rts


	      
OFFSET_ADD     DS.l  1    ;The offset into the MMU register structure
ADDRESS        DS.l  1    ;What code is to be executed in Supervisor mode
CONFIG         DS.l  1    ;Store exception vector #56
ILLEGAL        DS.l  1    ;Store exception vector #57
ACCESS         DS.l  1    ;Store exception vector #58
_MMU_PRESENT   DC.l  0    ;Assume no MMU
_EXCEPTION     DC.w  0    ;Where we keep the execption number
	       END	       















