; 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 ; heap block can move when resized, so make sure pointers fixed-up ; 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" ; Debug AMB,"growshrink ",r0,r1,r2 MOV R5,#AbsMaxAppSize 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_Npages] CMP R1,R3 Pull "R0,R2,R4,R5,LR",EQ ; done if no change BEQ SLVK MOV R5,R3 ; R5 := old no. pages BLT gs_shrink ;grow BL grwshr_node ; grow node itself first BVS gs_done ; failed node grow is not error - means grow by 0 BL growpages ; grow the slot (MMU mapping) STRVS R0,[SP] Pull "R0,R2,R4,R5,LR",VS BVS SLVK_SetV B gs_done gs_shrink BL shrinkpages ; shrink the slot (MMU mapping) first BLVC grwshr_node ; shrink node itself STRVS R0,[SP] Pull "R0,R2,R4,R5,LR",VS BVS SLVK_SetV gs_done MOV R3,R5 ;old no. of pages CMP R2,#0 ;also clears V MOVEQ R1,#0 LDRNE R1,[R2,#AMBNode_Npages] CMP R2,#0 ;0 for freed node STREQ R2,[SP,#4] ;poke freed handle to saved R2 Pull "R0,R2,R4,R5,LR" B SLVK ;handle grow/shrink of node itself ;entry: ; R1 = new no. of pages ; R2 -> node ; R5 = old no. of pages ;exit: ; R2 -> node (may be moved) grwshr_node Push "R0,R3,R4,LR" CMP R1,#0 BEQ grwshrn_free ;shrunk to nothing MOV R3,#(AMBNode_pages - AMBNode_id) ;new size excluding page list ADD R3,R3,R1,LSL #2 ;new size MOV R4,R2 ;so we can check for moved block BL AMB_BlockResize MOVVS R2,R4 ;in case block ptr not preserved on error BVS grwshrn_done ;fix-up links if block has moved CMP R4,R2 BEQ grwshrn_done LDR R3,[R2,#AMBNode_prev] STR R2,[R3,#AMBNode_next] ;fix prev_next LDR R3,[R2,#AMBNode_next] STR R2,[R3,#AMBNode_prev] ;fix next_prev LDR R3,AMBMappedInNode CMP R3,R4 STREQ R2,AMBMappedInNode ;fix MappedInNode if it matches LDR R3,[R2,#AMBNode_handle] LDR R4,AMBNodeHandles STR R2,[R4,R3,LSL #2] ;fix node address in handle array grwshrn_done STRVS R0,[SP] Pull "R0,R3,R4,PC" grwshrn_free LDR R0,AMBNodeHandles LDR R4,[R2,#AMBNode_handle] ;put handle on free list LDR R3,[R0] ;current first free handle STR R3,[R0,R4,LSL #2] ;attach STR R4,[R0] ;new first free handle ;remove node from list LDR R0,[R2,#AMBNode_prev] ; R0 -> prev_node LDR R3,[R2,#AMBNode_next] ; R3 -> next_node STR R3,[R0,#AMBNode_next] ; prev_next := next_node STR R0,[R3,#AMBNode_prev] ; next_prev := prev_node LDR R0,AMBNtasks SUB R0,R0,#1 STR R0,AMBNtasks ;if this is the mapped-in node, then nothing is now mapped in LDR R0,AMBMappedInNode CMP R0,R2 MOVEQ R0,#0 STREQ R0,AMBMappedInNode BL AMB_BlockFree MOVVC R2,#0 B grwshrn_done LTORG [ ValidateAMBHandles badsghandle Pull "R0,R2,R4,R5,LR" B badhandle ] END