.TITLE ALC$VM - ALLOCATE VM BUFFER .SBTTL ALC$VM - TITLE PAGE .PSECT VMX$$$,RO,I .IDENT /V01.01/ .ENABL LC ; ; ************************************************************************ ; * ; THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS ONLY. DIGITAL EQUIPMENT * ; COMPUTER USER'S SOCIETY, DIGITAL EQUIPMENT CORPORATION, MONSANTO, AND * ; THE AUTHOR DISCLAIM ALL WARRANTIES ON THE PROGRAM, INCLUDING WITHOUT * ; LIMITATION, ALL IMPLIED WARRANTIES OF MERCHANTABLITY AND FITNESS. * ; * ; FULL PERMISSION AND CONSENT IS HEREBY GIVEN TO DECUS AND TO THE DECUS * ; SPECIAL INTEREST GROUPS TO REPRODUCE, DISTRIBUTE, AND PUBLISH AND * ; PERMIT OTHERS TO REPRODUCE IN WHOLE OR IN PART, IN ANY FORM AND * ; WITHOUT RESTRICTION, THIS PROGRAM AND ANY INFORMATION RELATING TO IT. * ; * ; ************************************************************************ ; ; ALLOCATE VM BUFFER ; ; VERSION: V01.01 ; ; AUTHOR: R.W. STAMERJOHN MAPC 03-NOV-81 ; ; MODIFICATION HISTORY: ; ; V01.01 RWS 03-NOV-81 INITIAL VERSION ; .SBTTL ALC$VM - DECLARATIONS .DSABL GBL .DSABL CRF ; ; MACRO LIBRARY CALLS: ; ; NONE. ; ; GLOBAL DECLARATIONS: ; .GLOBL ALC$VM ;Module entry ; ; GLOBAL REFERENCES: ; ; VM subroutines. ; .GLOBL MAP$VI ;Map virtual address .GLOBL MRK$VI ;Mark virtual address written .GLOBL NEW$VI ;Allocate addition space .GLOBL SBF$VI ;Process allocation size .ENABL CRF .SBTTL ALC$VM * ALLOCATE VM BUFFER ; ;+ ; This routine allocates a VM buffer by searching the free list for an ; available buffer. The allocation is by first fit from the bottom of ; the available buffer space. If no space found, NEW$VI called to attempt ; to allocate additional space. If succesful, allocation is retried. ; ; INPUT: ; ; Call by: JSR PC,ALC$VM ; ; R3 = Buffer size to allocate ; ; OUTPUT: ; ; R0,R1 = Virtual address of allocated buffer ; R3 = Actual buffer size allocated ; ; REGISTERS: ; ; Uses: R0-R5 Saves: R3 Stack: 7 words ;- ALC$VM:: ;Ref label ; ; Process allocation size and set allocation increment for mapping use. ; CALL SBF$VI ;Check and process allocation size CLR -(SP) ;Save space on stack for previous CLR -(SP) ; ... free cell pointer MOV R3,R2 ;Copy size to allocate MOV R5,R3 ; ... to allocation increment ; ; Initialize starting VM address to header cell. ; CLR R0 ;Initialize VM address CLR R1 ; ... to header cell ; ; Map current cell and check if sufficient space for allocation. ; 1000$: CALL MAP$VI ;Map the current cell TST 4(R5) ;Is cell large enough? BNE 2000$ ; If NE - yes, continue CMP 6(R5),R2 ;Is cell large enough? BHIS 2000$ ; If HIS - yes, continue ; ; Test for another free buffer and if none, attempt to allocate more pool. ; 1100$: TST (R5) ;Is there another free buffer? BNE 1200$ ; If NE - yes, continue TST 2(R5) ;Is there another free buffer? BNE 1200$ ; If NE - yes, continue CALL NEW$VI ;Attempt to allocate more pool BR 1000$ ; and try to allocate it ; ; Advance to next cell in free list and loop. ; 1200$: MOV R1,2(SP) ;Copy address of this cell MOV R0,(SP) ; ... in case we must relink MOV (R5)+,R0 ;Get next cell address MOV (R5)+,R1 ; ... in free pool list BR 1000$ ; And retry allocation ; ; Allocate cell and update free list pointers. ; 2000$: CALL MRK$VI ;Mark address as written SUB R2,6(R5) ;Subtract allocated space from SBC 4(R5) ; ... size of current cell ADD 6(R5),R1 ;Get virtual address of the ADC R0 ; ... new allocated buffer ADD 4(R5),R0 ; ... from end of free buffer TST 4(R5) ;Is there still space in free buffer? BNE 9999$ ; If NE - still some space left TST 6(R5) ;Check low word for space? BNE 9999$ ; If NE - yes, continue on ; ; Used up a free buffer entirely, map next free buffer into previous one. ; MOV R0,-(SP) ;Save address of allocated buffer MOV R1,-(SP) ; ... to free up registers MOV (R5)+,-(SP) ;Save address of next free buffer MOV (R5)+,-(SP) ; ... for later restore MOV 10(SP),R0 ;Get address of previous buffer MOV 12(SP),R1 ; ... CALL MAP$VI ;Map this buffer CALL MRK$VI ; and mark it written MOV (SP)+,(R5)+ ;Store address of new VM free MOV (SP)+,(R5)+ ; ... pool in previous buffer MOV (SP)+,R1 ;Restore allocated VM address MOV (SP)+,R0 ; ... for return to caller ; ; Exit routine. ; 9999$: ADD #4,SP ;Clean stack MOV R2,R3 ;Restore allocation size RETURN ;Return to caller .END