.TITLE DEA$VM - DEALLOCATE VM BUFFER .SBTTL DEA$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. * ; * ; ************************************************************************ ; ; DEALLOCATE VM BUFFER ; ; VERSION: V01.01 ; ; AUTHOR: R.W. STAMERJOHN MAPC 03-NOV-81 ; ; MODIFICATION HISTORY: ; ; V01.01 RWS 03-NOV-81 INITIAL VERSION ; .SBTTL DEA$VM - DECLARATIONS .DSABL GBL .DSABL CRF ; ; MACRO LIBRARY CALLS: ; ; NONE. ; ; GLOBAL DECLARATIONS: ; .GLOBL DEA$VM ;Module entry ; ; GLOBAL REFERENCES: ; ; VM subroutines. ; .GLOBL MAP$VI ;Map virtual address .GLOBL MRK$VI ;Mark virtual address dirty .GLOBL SBF$VI ;Check legal size .GLOBL S32$VI ;Check legal buffer .ENABL CRF .SBTTL DEA$VM * DEALLOCATE VM BUFFER ; ;+ ; This routine deallocates a VM buffer by searching the current free ; free list for the correct place to return to new space. ; ; INPUT: ; ; Call by: JSR PC,DEA$VM ; ; R0,R1 = VM address of buffer ; R3 = Buffer size to deallocate ; ; OUTPUT: ; ; Always exits with success. Buffer is returned to free list ; and combined with other free buffers in necessary. ; ; REGISTERS: ; ; Uses: R0-R5 Saves: R2,R3 Stack: 9 words ;- DEA$VM:: ;Ref label ; ; Process deallocation size and set cell allocation increment for mapping. ; CALL S32$VI ;Check for legal buffer CALL SBF$VI ;Process deallocation size MOV R3,R2 ;Copy size of buffer to return MOV R5,R3 ;Copy cell allocation size ; ; Save virtual address of buffer we should return. ; MOV R1,-(SP) ;Save virtual address we MOV R0,-(SP) ; ... are returning to pool ; ; Initialize starting VM address to header cell. From here down, stack is ; as follows: ; ; R2 Size of buffer to return ; R3 Cell allocation incement ; ; SP+00 VM_Address of return cell (high) ; SP+02 VM_Address of return cell (low) ; CLR R0 ;Initialize VM address CLR R1 ; ... to header cell ; ; Map current cell and check if allocate space belongs here. ; 1000$: CALL MAP$VI ;Map current cell CMP (R5),(SP) ;Check high part of next address BLO 2000$ ; If LO - buffer fits in here BHI 1100$ ; If HI - buffer does not fit CMP 2(R5),2(SP) ;Check low part of address BLO 2000$ ; If LO - buffer fits in here ; ; Advance to next buffer in free list and repeat check. ; 1100$: MOV (R5)+,R0 ;Get next virtual address MOV (R5)+,R1 ; ... in free pool list BR 1000$ ;And loop ; ; Found place to return buffer. First check if buffer falls at end of ; current buffer. If so, update size of current buffer. ; 2000$: SUB 6(R5),2(SP) ;Back up returning buffer SBC (SP) ; ... in double precsision SUB 4(R5),(SP) ; ... to check if new buffer is at end CMP R0,(SP) ;Does the new buffer append to current? BLO 2100$ ; If LO - no, continue CMP R1,2(SP) ;Check low part of address BLO 2100$ ; If LO - no, continue ADD R2,6(R5) ;Add returning size to current buffer ADC 4(R5) ; ... in double precision CALL MRK$VI ;Mark virtual address as written BR 2200$ ;And continue ; ; Buffer is non-contiguous to current, store pointer to new buffer and ; map new buffer to next free slot. First restore virtual address. ; 2100$: ADD 6(R5),2(SP) ;Get actual VM address back ADC (SP) ; ... by revserving process ADD 4(R5),(SP) ; ... in double precsision MOV (R5)+,-(SP) ;Save virtual address of next MOV (R5)+,-(SP) ; ... free buffer MOV 6(SP),-(R5) ;Store virtual address of MOV 4(SP),-(R5) ; ... new free buffer MOV (R5)+,R0 ;Copy virtual address of MOV (R5)+,R1 ; ... new free buffer CALL MAP$VI ;Map this address CALL MRK$VI ; and mark as written MOV (SP)+,(R5)+ ;Link in address of next buffer MOV (SP)+,(R5)+ ; ... in free list CLR (R5)+ ;Store size of deallocated buffer MOV R2,(R5)+ ;Store size of deallocated buffer SUB #10,R5 ;Point back to beginning ; ; Check if new buffer is directly in front of next buffer in free list. ; If so, make one allocation from the two. ; 2200$: MOV R1,-(SP) ;Copy current buffer address MOV R0,-(SP) ; ... as double word address ADD 6(R5),R1 ;Get end of current buffer ADC R0 ; ... by adding in size of buffer ADD 4(R5),R0 ; ... in double precision CMP R0,(R5)+ ;Does next link abut this segment? BLO 2210$ ; If LO - no, continue CMP R1,(R5)+ ;Does next link abut this segment? BLO 2210$ ; If LO - no, continue MOV -(R5),R1 ;Get address of next segment MOV -(R5),R0 ; ... as a double word CALL MAP$VI ;Map this address MOV (R5)+,-(SP) ;Save link to next segment MOV (R5)+,-(SP) ; ... as a double word MOV (R5)+,-(SP) ;Save size of next segment MOV (R5)+,-(SP) ; ... as a double word MOV 10(SP),R0 ;Get old segment address back again MOV 12(SP),R1 ; ... as a double word CALL MAP$VI ;Map old address back CALL MRK$VI ; and mark as written MOV (SP)+,(R5)+ ;Store link to next free cell MOV (SP)+,(R5)+ ; ... as a double word ADD (SP)+,(R5)+ ;Update size of this cell ADD (SP)+,(R5) ; ... add in low part of size ADC -(R5) ; ... in double precision 2210$: ADD #4,SP ;Clean stack ; ; Exit routine. ; 9999$: ADD #4,SP ;Clean stack MOV R2,R3 ;Restore buffer size RETURN ;Return to caller .END