; 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.allocate ; handle allocate reason code ; entry: ; R0 = 0 (reason code 0) ; R1 = number of pages ; ; exit: ; R1 = no. of pages actually allocated ; R2 = handle for allocation allocate Push "R0,R3,R4,LR" MOV R3,#AbsMaxAppSize SUB R3,R3,#ApplicationStart MOV R3,R3,LSR #Log2PageSize ;R3 = absolute max app pages CMP R1,R3 MOVGT R1,R3 ;get handle for node LDR R0,AMBNodeHandles LDR R4,[R0] CMP R4,#0 ;any handles available? BNE %FT01 [ {TRUE} ; give up Pull "R0,R3,R4,LR" ADR R0,err_nomorehandles B SLVK_SetV ] [ {FALSE} ; oh no we don't, we're not a module now ;try to extend handles array MOV R2,R0 MOV R0,#ModHandReason_ExtendBlock MOV R3,#(GrowMaxNodes:SHL:2) SWI XOS_Module BVS alloc_done MOV R0,R2 STR R0,AMBNodeHandles ;in case block has moved LDR R3,AMBNhandles STR R3,[R0] ;first free handle now ADD LR,R3,#GrowMaxNodes STR LR,AMBNhandles ADD R4,R0,R3,LSL #2 ADD R3,R3,#1 ;put new handles on free list 00 STR R3,[R4],#4 ADD R3,R3,#1 CMP R3,LR BNE %BT00 MOV R3,#0 STR R3,[R4] ;0 = end of list LDR R4,[R0] ;now we have a useable handle ] 01 ;get memory for node - from RMA MOV R3,#(AMBNode_pages - AMBNode_id) ;size excluding page list ADD R3,R3,R1,LSL #2 ;plus one word per page MOV R0,#ModHandReason_Claim BL XROS_Module BVS alloc_done ;remember handle in node STR R4,[R2,#AMBNode_handle] ;init fields of new node LDR R4,=AMBMagicNodeID STR R4,[R2,#AMBNode_id] ;magic id MOV R4,#0 STR R4,[R2,#AMBNode_Npages] ;number of pages = 0 (so far) MOV R4,#ApplicationStart STR R4,[R2,#AMBNode_startaddr] LDR R4,=AppSpaceDANode LDR R4,[R4,#DANode_Flags] AND R4,R4,#&7F STR R4,[R2,#AMBNode_PPL] ;PPL from bottom 8 bits of DA flags ;do the actual MMU page allocation (grow from 0), for R1 pages, using node R2 BL growpages BVS alloc_done CMP R1,#0 ;EQ status if we were asked for 0 pages LDR R1,[R2,#AMBNode_Npages] ;actual no. of pages we achieved BEQ alloc_ok ;if asked for 0, regard as ok CMP R1,#0 BEQ alloc_zeropages ;achieving 0 pages is not ok ;ok, so remove handle from free list alloc_ok LDR R0,AMBNodeHandles LDR R4,[R2,#AMBNode_handle] LDR R3,[R0,R4,LSL #2] ;next free handle STR R3,[R0] ;store as new first free handle STR R2,[R0,R4,LSL #2] ;and remember node address in handle array ;R2 -> new node - put it on front of list ADR R3,AMBAnchorNode ; R3 -> ank_node LDR R4,[R3,#AMBNode_next] ; R4 -> old_node (old front) STR R4,[R2,#AMBNode_next] ; new_next := old_node STR R2,[R3,#AMBNode_next] ; ank_next := new_node STR R3,[R2,#AMBNode_prev] ; new_prev := ank_node STR R2,[R4,#AMBNode_prev] ; old_prev := new_node LDR R4,AMBNtasks ADD R4,R4,#1 STR R4,AMBNtasks STR R2,AMBMappedInNode ;allocated node is also mapped in LDR R2,[R2,#AMBNode_handle] ;change address to handle alloc_done STRVS R0,[SP] Pull "R0,R3,R4,LR" B SLVK_TestV ;free page table space and return 0 handle alloc_zeropages MOV R0,#ModHandReason_Free BL XROS_Module MOV R1,#0 MOV R2,#0 B alloc_done LTORG END