; 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, 0 if pages were requested but none could be claimed allocate Push "R0,R3,R4,LR" ; Debug AMB,"allocate ",r0,r1 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 ; give up Pull "R0,R3,R4,LR" ADR R0,err_nomorehandles B SLVK_SetV 01 ;get memory for node - from system heap MOV R3,#(AMBNode_pages - AMBNode_id) ;size excluding page list ADD R3,R3,R1,LSL #2 ;plus one word per page BL AMB_BlockClaim 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,=ZeroPage+AppSpaceDANode LDR R4,[R4,#DANode_Flags] ;Get the page flags from the DA. LDR LR,=DynAreaFlags_AccessMask;Note that this is rather academic AND R4,R4,LR ;because various bits of code ignore STR R4,[R2,#AMBNode_PPL] ;or overwrite these 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 CLRV alloc_done ; Debug AMB,"<alloc ",r1,r2 STRVS R0,[SP] Pull "R0,R3,R4,LR" B SLVK_TestV ;free page table space and return 0 handle alloc_zeropages BL AMB_BlockFree MOV R1,#0 MOV R2,#0 B alloc_done LTORG END