; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; > s.mapslot

; handle mapping of entire slot in or out (bit 8 of R0 clear)
; or mapping of some of slot (bit 8 of R0 set)

; entry:
;     R0 = bits 0..7 = 3 (reason code 3); bit 8 set for mapsome
;     R1 = start (logical) address; 0 means application start; -1 means map out
;     R2 = handle
;     R3,R4 used if bit 8 set - see mapsome
;
; Note that if bit 8 is clear, the use is restricted to mapping in or out of
; whole slots only. Hence if bit 8 is clear, behaviour is undefined unless
; R1 is one of: 0, &8000 or -1.
;
mapslot

;  Debug AMB,"mapslot",r0,r1,r2,r3,r4

        TST     R0,#&100   ;if bit 8 set, then mapsome
        BNE     mapsome

        Push    "R0-R6,LR"

        MOVS    R5,R1                    ;save entry R1
        MOVEQ   R5,#ApplicationStart     ;0 means application start

      [ ValidateAMBHandles
        ;validate handle
        LDR     R0,AMBNhandles
        CMP     R2,R0
        BGT     badmapslot
        CMP     R2,#1
        BLT     badmapslot
      ]

        LDR     R0,AMBNodeHandles   ; R0 -> handle array
        LDR     R1,[R0,R2,LSL #2]   ; R1 -> node

      [ ValidateAMBHandles
        ;check we have a proper id for node handle
        LDR     R3,=AMBMagicNodeID
        LDR     LR,[R1,#AMBNode_id]
        CMP     LR,R3
        BNE     badmapslot
      ]

        LDR     R3,[R1,#AMBNode_Npages]
        ADD     R4,R1,#AMBNode_pages

;;;actually, we can have 0 page slots (eg. sometimes from pinboard)
;;;        CMP     R3,#0
;;;        BEQ     ms_done                   ;should not happen


        LDR   R2,AMBMappedInNode
        CMP   R1,R2
        CMPEQ R5,#-1
        BEQ   ms_domap     ;do map if already mapped in, and asked to map out

        CMP   R1,R2
        CMPNE R5,#-1
        BEQ   ms_done      ;else do map only if not already mapped in, and asked to map in

ms_domap
        CMP     R5,#-1                      ;EQ if it is a map out
        LDREQ   R6,=DuffEntry
        MOVNE   R6,#ApplicationStart
        STR     R6,[R1,#AMBNode_startaddr]
        MOVEQ   R6,#AP_Duff
        MOVNE   R6,#0
        STR     R6,[R1,#AMBNode_PPL]

  [ AMB_LazyMapIn
        LDRNE   R2,AMBNContextSwitches
        ADDNE   R2,R2,#1
        STRNE   R2,AMBNContextSwitches
        LDR     R2,AMBFlags
        TST     R2,#AMBFlag_LazyMapIn_disable :OR: AMBFlag_LazyMapIn_suspend
        BNE     ms_cantbelazy
        ;
        ; - if map out, do sparse map out of whole page list then zero AMBMappedInNpages
        ; - if map in, just zero AMBMappedInNpages (last map out will have cleared AMBMappedInRegister)
        ;
        MOV     R2,R5
        CMP     R2,#-1
        LDREQ   R3,AMBMappedInNpages
        ADREQ   R5,AMBMappedInRegister
        LDREQ   R6,[R1,#AMBNode_Npages]
        ;entry: R3 = no. pages mapped in, R4 -> list of page entries,
        ;       R5 -> bitmap of pages mapped in, R6=total no. of pages in page list
        BLEQ    AMB_SetMemMapEntries_SparseMapOut
        MOV     R3,#0
        STR     R3,AMBMappedInNpages
        MOV     R5,R2
        B       ms_mapdone
ms_cantbelazy
        ;entry: R3 = no. of pages, R4 -> list of page entries,
        ;       R5 := start logical address, R6 = PPL
        BL      AMB_SetMemMapEntries
ms_mapdone
  |
        ;entry: R3 = no. of pages, R4 -> list of page entries,
        ;       R5 := start logical address, R6 = PPL
        BL      AMB_SetMemMapEntries
  ]

;update AppSpace kernel stuff
        LDR     R2,[R1,#AMBNode_Npages]
        LDR     R3,=ZeroPage+AppSpaceDANode
        MOV     R0,#ApplicationStart
        CMP     R5,#-1
        ADDNE   R0,R0,R2,LSL #Log2PageSize
        STR     R0,[R3,#DANode_Size]
        LDR     R3,=ZeroPage
        STR     R0,[R3,#MemLimit]
        CMP     R5,#-1
        MOVEQ   R3,#0
        MOVNE   R3,R1
        STR     R3,AMBMappedInNode

ms_done
;;;        STRVS   R0,[SP]
        CLRV
        Pull    "R0-R6,LR"
        B       SLVK_TestV

        LTORG

      [ ValidateAMBHandles
badmapslot
        Pull    "R0-R6,LR"
        B       badhandle
      ]

    END