; 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.mapsome

; handle mapping in of some of slot
; (used to implement 'mapenoughslot' for Wimp_TransferBlock)

; entry:
;     R0 = &103 (reason code 3, bit 8 set for mapsome)
;     R1 = start (logical address)
;     R2 = handle
;     R3 = offset to start of mapping (pages into slot)
;     R4 = no. of pages to map

mapsome
        Push    "R0-R7,LR"

      [ AMB_Debug
        Push    "LR"
        DebugReg r1, "mapsome "
        DebugReg r2
        DebugReg r3
        DebugReg r4
        Pull    "LR"
      ]

        CMP     R1,#0
        MOVEQ   R1,#ApplicationStart

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

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

      [ ValidateAMBHandles
        ;check we have a proper id for node handle
        LDR     R6,=AMBMagicNodeID
        LDR     LR,[R0,#AMBNode_id]
        CMP     LR,R6
        BNE     badmapsome
      ]

        LDR     R6,[R0,#AMBNode_DANode+DANode_PMPSize]
        ADD     LR,R3,R4
        CMP     LR,R6
        BGT     badmssize

        CMP     R1,#-1
        BEQ     mapsome_out

        Push    "R10"
        ADD     R10,R0,#AMBNode_DANode
        MOV     R5,R4
        SUB     R7,R1,#ApplicationStart
        RSB     R7,R3,R7,LSR #Log2PageSize ; offset = log page index - phys page index
        MOV     R1,R3
        BL      AMB_SetMemMapEntries_MapIn
        Pull    "R10"

        Pull    "R0-R7,LR"
        B       SLVK

mapsome_out
        ; Yuck - the memmap operations need to know the logical address, but we haven't been told what it is
        ; Do a physical to logical translation on the first page in the region to work out where it is
        Push    "r10"
        ADD     R10,R0,#AMBNode_DANode
        LDR     R7,[R10,#DANode_PMP]
        LDR     R7,[R7,R3,LSL #2] ; Get PPN for PMP page
        LDR     R1,=ZeroPage+CamEntriesPointer
        LDR     R1,[R1]
        ASSERT  CAM_LogAddr=0
        LDR     R7,[R1,R7,LSL #CAM_EntrySizeLog2] ; Get log addr for PPN
        SUB     R7,R7,#ApplicationStart
        MOV     R1,R3 ; Physical index within PMP to start from
        RSB     R7,R3,R7,LSR #Log2PageSize ; offset = log page index - phys page index
        MOV     R5,R4 ; Number of pages
        BL      AMB_SetMemMapEntries_MapOut
        Pull    "r10"

        Pull    "R0-R7,LR"
        B       SLVK


    LTORG

badmssize
;return with V set but no error block (Wimp handles that)
        Pull    "R0-R7,LR"
        B       SLVK_SetV

      [ ValidateAMBHandles
badmapsome
        Pull    "R0-R7,LR"
        B       badhandle
      ]

    END