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

; change number of pages in slot (grow/shrink)

; entry:
;     R0 = 2 (reason code 2)
;     R1 = new number of pages required
;     R2 = handle
;
; exit:
;     R1 = new number of pages actually achieved
;     R2 = 0 if AMB handle freed (else preserved)
;     R3 = old number of pages

growshrink

        Push    "R0,R2,R4,R5,LR"

      [ AMB_Debug
        DebugReg r1, "growshrink "
        DebugReg r2
      ]

        LDR     R5,=ZeroPage
        LDR     R5,[R5,#SoftAplWorkMaxSize]
        SUB     R5,R5,#ApplicationStart
        MOV     R5,R5,LSR #Log2PageSize   ;R5 = absolute max app pages
        CMP     R1,R5
        MOVGT   R1,R5

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

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

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

        LDR     R3,[R2,#AMBNode_DANode+DANode_PMPSize]
        CMP     R1,R3
        BEQ     gs_done                ; done if no change

        SUB     R1,R1,R3
        ADD     R2,R2,#AMBNode_DANode
      [ {FALSE} ; Currently batcalls on PMPs will treat the PMP as if it were a regular DA (necessary for the PMP page claim implementation) - so just call our DA handler directly
        MOV     R0,#ChangeDyn_Batcall
        MOV     R1,R1,LSL #Log2PageSize
        SWI     XOS_ChangeDynamicArea  ; Make batcall so we can specify our node
      |
        Push    "R12"
        MOV     R0,#DAHandler_ResizePMP
        ASSERT  DANode_Handler = DANode_Workspace + 4
        ADD     R12,R2,#DANode_Workspace
        MOV     LR,PC
        LDMIA   R12,{R12,PC}
        Pull    "R12"
      ]
      [ AMB_Debug
        BVC     %FT50
        LDR     r0, [r0]
        DebugReg r0, "growshrink CDA err "
50
;        DebugReg r1, "growshrink CDA result "
      ]
        LDR     R1,[R2,#DANode_PMPSize]
        CMP     R1,#0                  ; if shrunk to zero
        LDR     R2,[R2,#AMBNode_handle-AMBNode_DANode]
        BNE     gs_done
        MOV     R0,#AMBControl_Deallocate
        SWI     XOS_AMBControl         ; then completely free the node
        MOV     R2,#0
        STR     R2,[SP,#4]               ;poke freed handle to saved R2
gs_done
      [ AMB_Debug
        DebugReg r1, "<growshrink "
        DebugReg r2
        DebugReg r3
      ]
        Pull    "R0,R2,R4,R5,LR"
        B       SLVK

        LTORG


      [ ValidateAMBHandles
badsghandle
        Pull    "R0,R2,R4,R5,LR"
        B       badhandle
      ]


    END