

; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 1

;

;00100  0001	MODULE LIB$VM (		! Virtual memory allocation/deallocation

;00200  0002		IDENT = '02-26'	! File: LVM.B32

;00300  0003			) =

;00400  0004	BEGIN

;00500  0005	

;00600  0006	!

;00700  0007	! Copyright (C) 1977

;00800  0008	! Digital Equipment Corporation,  Maynard, Massachusetts  01754

;00900  0009	!

;01000  0010	! This software is furnished under a license for use only on  a

;01100  0011	! single computer system and may be copied only with the inclu-

;01200  0012	! sion of the above copyright notice.  This  software,  or  any

;01300  0013	! other  copies  thereof, may not be provided or otherwise made

;01400  0014	! available to any other person except for use on  such  system

;01500  0015	! and  to  one who agrees to these license terms.  Title to and

;01600  0016	! ownership of the software shall at all times remain in DEC.

;01700  0017	!

;01800  0018	! The information in this software is subject to change without

;01900  0019	! notice and should not be construed as a commitment by Digital

;02000  0020	! Equipment Corporation.

;02100  0021	!

;02200  0022	! DEC assumes no responsibility for the use or  reliability  of

;02300  0023	! its software on equipment which is not supplied by DEC.

;02400  0024	!

;02500  0025	!++

;02600  0026	! FACILITY: Resource allocation library

;02700  0027	!

;02800  0028	! ABSTRACT:  Dynamic virtual memory allocation and deallocation.

;02900  0029	!

;03000  0030	!	Dynamic virtual memory allocation and deallocation.

;03100  0031	!	This facility is the only user mode procedure for allocating

;03200  0032	!	and deallocation virtual memory.  By having all procedures use

;03300  0033	!	this facility, allocation conflict is eliminated.

;03400  0034	!

;03500  0035	! ENVIRONMENT: User access mode; mixture of AST level or not.

;03600  0036	!

;03700  0037	! AUTHOR:	Trevor J. Porter, CREATION DATE: 14-Jan-77; Version 01

;03800  0038	!

;03900  0039	! MODIFIED BY:

;04000  0040	!

;04100  0041	!	Thomas N. Hastings, 31-may-77: Version 02

;04200  0042	! 01	- original in linker

;04300  0043	! 02-10	- Add new entry point names LIB$GET_VM, LIB$FREE_VM.  TNH 8-Oct-77

;04400  0044	! 02-15	- Use RTLMSG error codes.  TNH 21-Nov-77

;04500  0045	! 02-16	- Change LIB$_NORMAL to LIB$_NORMAL.  TNH 21-Nov-77

;04600  0046	! 02-17	- Don't clear memory.  TNH 19-Dec-77.

;04700  0047	! 02-18	- Remove LIB$VM_GET, LIB$VM_RET entry points.  TNH 30_Jan-78

;04800  0048	! 02-19	- Change expand size to 128., keep track of largest area

;04900  0049	!	  allocated so far for validity check in FREE_VM.  JMT 5-Mar-78

;05000  0050	! 02-22	- Change REQUIRE files for VAX system build.  DGP 28-Apr-78

;05100  0051	! 02-23	- Return SS$_NORMAL instead of LIB$_NORMAL.  TNH 15-July-78

;05200  0052	! 02-24	- Use partial allocation from $EXPREG.  TNH 29-July-78

;05210  0053	! 02-25	- Don't initialize MINADDRESS.  TNH 31-July-78

;05300  0054	!--



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 2

;

;00100  0055	!

;00200  0056	! TABLE OF CONTENTS:

;00300  0057	!

;00400  0058	

;00500  0059	FORWARD ROUTINE

;00600  0060		LIB$GET_VM,	! Allocate virtual memory - interface

;00700  0061		ALLOCATE,	! Allocate virtual memory - body

;00800  0062		LIB$FREE_VM,	! Deallocate virtual memory - interface

;00900  0063		DEALLOCATE;	! Deallocate virtual memory - body

;01000  0064	

;01100  0065	

;01200  0066	!

;01300  0067	! INCLUDE FILES:

;01400  0068	!

;01500  0069	

;01600  0070		REQUIRE 'RTLIN:LPSECT';	! Define DECLARE_PSECTS macro

; %PRINT:	 REQUIRE FILE: LPSECT.B32, VERSION 01-5, TNH, 27-Jun-78

;01700  0124	

;01800  0125	!

;01900  0126	! MACROS:

;02000  0127	!

;02100  0128	!	NONE

;02200  0129	!

;02300  0130	! EQUATED SYSMBOLS:

;02400  0131	!

;02500  0132	

;02600  0133	LITERAL

;02700  0134		K_VM_MAX_ADR = %X'40000000',	! Max. possible address (in control region)dd

;02800  0135		K_EXPAND_SIZE = 128;		! No. of pages to expand program region each call

;02900  0136						! to the operating system when free list cannot satisfy request

;03000  0137	

;03100  0138	!

;03200  0139	! PSECT DECLARATIONS:

;03300  0140	!

;03400  0141	

;03500  0142		DECLARE_PSECTS (LIB);	! declare PSECTs LIB LIB$ facility

;03600  0143	

;03700  0144	!

;03800  0145	! OWN STORAGE:

;03900  0146	!

;04000  0147	

;04100  0148	OWN

;04200  0149		MINADDRESS : INITIAL(0),		! LOWEST ADDRESS EVER ALLOCATED

;04210  0150							! 0 is special case

;04300  0151		MAXSIZE: INITIAL(0),			! MAX size allocated so far

;04400  0152		NEWBLOCK : REF VECTOR[2],		! CURRENT BLOCK POINTER

;04500  0153		NEXTBLOCK : REF VECTOR[2],		! NEXT BLOCK POINTER

;04600  0154		LASTBLOCK : REF VECTOR[2],		! PREVIOUS BLOCK POINTER

;04700  0155	

;04800  0156		Q_LIST_HEAD: VECTOR[2] INITIAL (0, 0);	! Free memory list head

;04900  0157	

;05000  0158	! EXTERNAL REFERENCES:

;05100  0159	!

;05200  0160	EXTERNAL ROUTINE

;05300  0161		SYS$EXPREG: ADDRESSING_MODE(GENERAL);	! Expand (program) region system service



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 2-1

;

;05400  0162	

;05500  0163	EXTERNAL LITERAL

;05600  0164		SS$_NORMAL: UNSIGNED (6),	! Library success code

;05700  0165		LIB$_BADBLOADR: UNSIGNED (32),	! BAD BLOCK ADDRESS

;05800  0166		LIB$_BADBLOSIZ: UNSIGNED (32),	! BAD BLOCK SIZE

;05900  0167		LIB$_FATERRLIB: UNSIGNED (32),	! FATAL ERROR IN LIBRARY

;06000  0168		LIB$_INSVIRMEM: UNSIGNED (32);	! INSUFFICIENT VIRTUAL MEMORY



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 3

;

;00100  0169	GLOBAL ROUTINE LIB$GET_VM (	! Allocate dynamic virtual memory

;00200  0170		NUM_BYTES,		! Adr. of longword size in bytes

;00300  0171		BLK_ADR)		! Adr. of longword to receive assigned adr.

;00400  0172		=

;00500  0173	

;00600  0174	!++

;00700  0175	! FUNCTIONAL DESCRIPTION:

;00800  0176	!

;00900  0177	!       Allocates n virtually contiguous bytes at an arbitrary  place  in

;01000  0178	!       the  program  region and returns the virtual address of the first

;01100  0179	!       byte.  The number of bytes is rounded up  so  that  the  smallest

;01200  0180	!       number  of whole quad words (8 bytes) are allocated starting at a

;01300  0181	!       quad word boundary.  Procedures cannot count on a successive call

;01400  0182	!       to allocate a block of bytes which is virtually contiguous to the

;01500  0183	!       ones obtained on a previous call (since an AST  or  exception  or

;01600  0184	!       called  procedure  could  also  have  asked  for virtual memory).

;01700  0185	!       Usually, the bytes are  allocated  at  the  end  of  the  Program

;01800  0186	!       region.   However, if there is a sufficiently large hole, it will

;01900  0187	!       be used instead.  Should there not be enough virtual memory

;02000  0188	!	of the required size, the operating  system

;02100  0189	!       is  called to expand the program region by K_EXPAND_SIZE*512 bytes.

;02200  0190	!       The new area is linked (by deallocating it ) into the  free  list

;02300  0191	!       and  the  requested  memory is allocated from the free list.  The

;02400  0192	!       free list is  therefore  initialized  on  first  allocaton  call.

;02500  0193	!	AST and non-AST levels are assigned from differrent pools.

;02600  0194	!  

;02700  0195	!  CALLING SEQUENCE:

;02800  0196	!  

;02900  0197	!       STATUS.WLC.V = LIB$GET_VM   (NUM_BYTES.RLU.R,  BASE_ADR.WA.R

;03000  0198	!       [,BEST_FIT.RB.R]

;03100  0199	!  

;03200  0200	!  INPUT PARAMETERS:

;03300  0201	!  

;03400  0202	!       num_bytes is  the  address  of  an  unsigned   longword   integer

;03500  0203	!                 specifying  the number of virtually contiguous bytes to

;03600  0204	!                 be  allocated.   Sufficient  pages  are  allocated   to

;03700  0205	!                 satisfy  the  request.  however, the program should not

;03800  0206	!                 reference  before  the  first  byte  address   assigned

;03900  0207	!                 (base_address)    beyond   the   last   byte   assigned

;04000  0208	!                 (base_adr+num_bytes - 1) since it may  be  assigned  to

;04100  0209	!                 another procedure.

;04200  0210	!  

;04300  0211	!       best_fit  is the address of an optional flag byte  which  if  bit

;04400  0212	!                 0=1  specifies  that the best fit is to be found, i.e.,

;04500  0213	!                 the fit which leaves  the  smallest  unused  number  of

;04600  0214	!                 bytes above the assigned area.  if bit 0=0 or num_bytes

;04700  0215	!                 is not present, a first fit algorithm will be used.

;04800  0216	!  

;04900  0217	!  OUTPUT PARAMETERS:

;05000  0218	!  

;05100  0219	!                 base_adr the address of a longword which is set to  the

;05200  0220	!                 first  virtual address of the newly assigned contiguous

;05300  0221	!                 block of bytes.

;05400  0222	!  

;05500  0223	!  IMPLICIT INPUTS:



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 3-1

;

;05600  0224	!  

;05700  0225	!       Own storage is used to keep track of  unallocated  pages  in  the

;05800  0226	!       program  region.   The  first  call  after  an image is activated

;05900  0227	!       causes the OWN storage to be initialized.

;06000  0228	!  

;06100  0229	!  IMPLICIT OUTPUTS:

;06200  0230	!  

;06300  0231	!       None.

;06400  0232	!  

;06500  0233	!  COMPLETION STATUS:

;06600  0234	!  

;06700  0235	!       SS$_NORMAL indicates normal successful completion.

;06800  0236	!       LIB$_INSVIRMEM indicates 'INSUFFICIENT VIRTUAL MEMORY' when the

;06900  0237	!       program

;07000  0238	!       region was attempted to be expanded.

;07100  0239	!       LIB$_BADBLOSIZ indicates 'BAD BLOCK SIZE (0)

;07200  0240	!       No partial assignment is made.

;07300  0241	!  

;07400  0242	!  SIDE EFFECTS:

;07500  0243	!       An appropriate number of virtual byes are removed from the  image

;07600  0244	!       free  memory  list.   If needed the program region is expanded by

;07700  0245	!       calling the SYS$EXPREG system service.  

;07800  0246	!--

;07900  0247	

;08000  0248	    BEGIN

;08100  0249	    LOCAL

;08200  0250		STATUS,

;08300  0251		L_BLK_SIZE;			! size of block in bytes modulo quad word

;08400  0252	

;08500  0253	    L_BLK_SIZE = (..NUM_BYTES + 7) AND ( NOT 7);		! ROUND UP TO MULTIPLE OF 8 BYTES

;08600  0254	    IF .L_BLK_SIZE EQL 0

;08700  0255	    THEN

;08800  0256		RETURN LIB$_BADBLOSIZ;		! 'BAD BLOCK SIZE'

;08900  0257	    IF (STATUS = ALLOCATE(.L_BLK_SIZE, .BLK_ADR))

;09000  0258	    THEN

;09100  0259		IF .L_BLK_SIZE GTRU .MAXSIZE

;09200  0260		THEN

;09300  0261		    MAXSIZE = .L_BLK_SIZE;

;09400  0262	    RETURN .STATUS;

;09500  0263	    END;		!  end of LIB$GET_VM routine





							    .TITLE  LIB$VM

							    .IDENT  \02-26\



							    .PSECT  LIB$DATA,NOEXE,  PIC,2



				    00000000  00000 MINADDRESS:

							    .LONG   0							      ;

				    00000000  00004 MAXSIZE:.LONG   0							      ;

					      00008 NEWBLOCK:

							    .BLKB   4

					      0000C NEXTBLOCK:

							    .BLKB   4

					      00010 LASTBLOCK:



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 3-2

;

							    .BLKB   4

			  00000000  00000000  00014 Q_LIST_HEAD:

							    .LONG   0, 0						      ;



							    .EXTRN  SYS$EXPREG, SS$_NORMAL, LIB$_BADBLOADR, LIB$_BADBLOSIZ

							    .EXTRN  LIB$_FATERRLIB, LIB$_INSVIRMEM



							    .PSECT  LIB$CODE,NOWRT,  SHR,  PIC,2



					 000C 00000 	    .ENTRY  LIB$GET_VM, Save R2,R3				      ; 0169

		         53 00000000'  EF  9E 00002 	    MOVAB   MAXSIZE, R3						      ;

	   50 	    04   BC	       07  C1 00009 	    ADDL3   #7, @NUM_BYTES, R0					      ; 0253

	   52 	         50 	       07  CB 0000E 	    BICL3   #7, R0, L_BLK_SIZE					      ;

				       08  12 00012 	    BNEQ    1$							      ; 0254

		         50 00000000G  8F  D0 00014 	    MOVL    #LIB$_BADBLOSIZ, R0					      ; 0256

					   04 0001B 	    RET     							      ;

				  08   AC  DD 0001C 1$:     PUSHL   BLK_ADR						      ; 0257

				       52  DD 0001F 	    PUSHL   L_BLK_SIZE						      ;

		  0000V  CF	       02  FB 00021 	    CALLS   #2, ALLOCATE					      ;

		         08 	       50  E9 00026 	    BLBC    STATUS, 2$						      ;

		         63 	       52  D1 00029 	    CMPL    L_BLK_SIZE, MAXSIZE					      ; 0259

				       03  1B 0002C 	    BLEQU   2$							      ;

		         63 	       52  D0 0002E 	    MOVL    L_BLK_SIZE, MAXSIZE					      ; 0261

					   04 00031 2$:     RET     							      ; 0169



; Routine Size:  50 bytes







; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 4

;

;00100  0264	ROUTINE ALLOCATE (SIZE,ADDRESS) =

;00200  0265	!

;00300  0266	!	ROUTINE TO DO ACTUAL ALLOCATION AND PROGRAM

;00400  0267	!	REGION EXPANSION

;00500  0268	!

;00600  0269	    BEGIN

;00700  0270	    LOCAL

;00800  0271		MEMLIMITS : VECTOR[2];

;00900  0272	

;01000  0273	    WHILE -1 DO

;01100  0274		BEGIN

;01200  0275		LASTBLOCK = Q_LIST_HEAD[0];		! INITIALLY AT TOP OF FREE LIST

;01300  0276	

;01400  0277		WHILE (NEWBLOCK=.LASTBLOCK[0]) NEQ 0 DO	! FOLLOW DOWN FREE LIST

;01500  0278		    BEGIN

;01600  0279		    IF .NEWBLOCK[1] EQL .SIZE		! LOOK FOR SUITABLE FREE BLOCK

;01700  0280		    THEN				! EXACT SIZE MATCH

;01800  0281			BEGIN

;01900  0282			LASTBLOCK[0] = .NEWBLOCK[0];	! SO LAST POINTS WHERE THIS ONE POINTED

;01950  0283			.ADDRESS = NEWBLOCK[0];

;02000  0284			IF NEWBLOCK[0] LSSU .MINADDRESS OR .MINADDRESS EQLU 0 ! NOW RECORD LOWEST

;02100  0285			THEN MINADDRESS = NEWBLOCK[0];	! ALLOCATED ADDRESS

;02200  0286			RETURN SS$_NORMAL;		! AND WE ARE DONE

;02300  0287			END;

;02400  0288	

;02500  0289		    IF .NEWBLOCK[1] GTRU .SIZE		! OR ONE LARGER THAN REQUESTED

;02600  0290		    THEN

;02700  0291			BEGIN

;02800  0292			NEXTBLOCK = NEWBLOCK[0]+.SIZE;	! IN WHICH CASE THERE IS A NEW

;02900  0293			NEXTBLOCK[0] = .NEWBLOCK[0];

;03000  0294			NEXTBLOCK[1] = .NEWBLOCK[1]-.SIZE; 	! NEXT BLOCK (THE PART REMAIN-

;03100  0295			LASTBLOCK[0] = NEXTBLOCK[0];	! ING) AFTER TAKING REQUESTED BLOCK OFF

;03150  0296			.ADDRESS = NEWBLOCK[0];

;03200  0297			IF NEWBLOCK[0] LSSU .MINADDRESS OR .MINADDRESS EQLU 0 ! NOW RECORD LOWEST

;03300  0298			THEN MINADDRESS = NEWBLOCK[0];		! ALLOCATED ADDRESS

;03400  0299			RETURN SS$_NORMAL;		! AND WE ARE DONE

;03500  0300			END;

;03600  0301	

;03700  0302		    LASTBLOCK = NEWBLOCK[0];	! WHEN NOT SUITABLE THIS BLOCK BECOMES PREVIOUS BLOCK

;03800  0303		    END;				! OF WHILE LOOP

;03900  0304	!

;04000  0305	!	AT THIS POINT WE HAVE REACHED THE END OF THE FREE

;04100  0306	!	MEMORY LIST WITHOUT FINDING A BLOCK OF REQUIRED SIZE.

;04200  0307	!	THUS, WE EXPAND THE ADDRESS SPACE AND ATTEMPT TO

;04300  0308	!	ALLOCATE FROM ADDITIONAL VIRTUAL MEMORY.

;04310  0309	!	IF PARTIAL ALLOCATION, USE ALL OF IT.

;04320  0310	!	MEMLIMITS[0] IS FIRST VIRTUAL ADDRESS ASSIGNED,

;04330  0311	!	AND MEMLIMITS[1] IF VIRTUAL ADDRESS OF LAST PAGE ASSIGNED.

;04340  0312	!	BOTH ARE -1 IF NOTHING WAS ABLE TO BE ASSIGNED.

;04400  0313	!

;04500  0314		SYS$EXPREG (K_EXPAND_SIZE, MEMLIMITS, ,);

;04600  0315		IF .MEMLIMITS[0] LSS 0

;04700  0316		THEN					! UNSUCCESSFULLY EXPANDED PROGRAM REGION

;04800  0317		    RETURN LIB$_INSVIRMEM;

;04900  0318	



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 4-1

;

;05000  0319		IF NOT DEALLOCATE ((.MEMLIMITS[1]-.MEMLIMITS[0]) + 1, .MEMLIMITS[0], LASTBLOCK[0])

;05100  0320		THEN

;05200  0321		    RETURN LIB$_FATERRLIB;		! should never happen

;05300  0322	

;05400  0323		END					! OF FOREVER LOOP

;05500  0324	    END;					! OF ALLOCATE ROUTINE











					 000C 00032 ALLOCATE:

							    .WORD   Save R2,R3						      ; 0264

		         53 00000000'  EF  9E 00034 	    MOVAB   LASTBLOCK, R3					      ;

		         5E 	       08  C2 0003B 	    SUBL2   #8, SP						      ;

		         63 	  04   A3  9E 0003E 1$:     MOVAB   Q_LIST_HEAD, LASTBLOCK				      ; 0275

		         52 	       63  D0 00042 2$:     MOVL    LASTBLOCK, R2					      ; 0277

		    F8   A3	       62  D0 00045 	    MOVL    (R2), NEWBLOCK					      ;

				       4A  13 00049 	    BEQL    8$							      ;

		         51 	  F8   A3  D0 0004B 	    MOVL    NEWBLOCK, R1					      ; 0279

		    04   AC	  04   A1  D1 0004F 	    CMPL    4(R1), SIZE						      ;

				       05  12 00054 	    BNEQ    3$							      ;

		         62 	       61  D0 00056 	    MOVL    (R1), (R2)						      ; 0282

				       1E  11 00059 	    BRB     4$							      ; 0283

		    04   AC	  04   A1  D1 0005B 3$:     CMPL    4(R1), SIZE						      ; 0289

				       2E  1B 00060 	    BLEQU   7$							      ;

		    FC   A3	  04 BC41  9E 00062 	    MOVAB   @SIZE[R1], NEXTBLOCK				      ; 0292

		         50 	  FC   A3  D0 00068 	    MOVL    NEXTBLOCK, R0					      ; 0293

		         60 	       61  D0 0006C 	    MOVL    (R1), (R0)						      ;

      04   A0	    04   A1	  04   AC  C3 0006F 	    SUBL3   SIZE, 4(R1), 4(R0)					      ; 0294

		         62 	       50  D0 00076 	    MOVL    R0, (R2)						      ; 0295

		    08   BC	       51  D0 00079 4$:     MOVL    R1, @ADDRESS					      ; 0296

		    F0   A3	       51  D1 0007D 	    CMPL    R1, MINADDRESS					      ; 0297

				       05  1F 00081 	    BLSSU   5$							      ;

				  F0   A3  D5 00083 	    TSTL    MINADDRESS						      ;

				       04  12 00086 	    BNEQ    6$							      ;

		    F0   A3	       51  D0 00088 5$:     MOVL    R1, MINADDRESS					      ; 0298

		         50 	       00G 9A 0008C 6$:     MOVZBL  S^SS$_NORMAL, R0					      ; 0299

					   04 0008F 	    RET     							      ;

		         63 	       51  D0 00090 7$:     MOVL    R1, LASTBLOCK					      ; 0302

				       AD  11 00093 	    BRB     2$							      ; 0277

				       7E  7C 00095 8$:     CLRQ    -(SP)						      ; 0314

				  08   AE  9F 00097 	    PUSHAB  MEMLIMITS						      ;

		         7E 	  80   8F  9A 0009A 	    MOVZBL  #128, -(SP)						      ;

	      00000000G  00	       04  FB 0009E 	    CALLS   #4, SYS$EXPREG					      ;

		         50 	       6E  D0 000A5 	    MOVL    MEMLIMITS, R0					      ; 0315

				       08  18 000A8 	    BGEQ    9$							      ;

		         50 00000000G  8F  D0 000AA 	    MOVL    #LIB$_INSVIRMEM, R0					      ; 0317

					   04 000B1 	    RET     							      ;

				       63  DD 000B2 9$:     PUSHL   LASTBLOCK						      ; 0319

				       50  DD 000B4 	    PUSHL   R0							      ;

	   50 	    0C   AE	       50  C3 000B6 	    SUBL3   R0, MEMLIMITS+4, R0					      ;

				  01   A0  9F 000BB 	    PUSHAB  1(R0)						      ;

		  0000V  CF	       03  FB 000BE 	    CALLS   #3, DEALLOCATE					      ;

		         03 	       50  E9 000C3 	    BLBC    R0, 10$						      ;



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 4-2

;

				     FF75  31 000C6 	    BRW     1$							      ;

		         50 00000000G  8F  D0 000C9 10$:    MOVL    #LIB$_FATERRLIB, R0					      ; 0321

					   04 000D0 	    RET     							      ; 0264



; Routine Size:  159 bytes







; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 5

;

;00100  0325	GLOBAL ROUTINE LIB$FREE_VM (		! Deallocate virtual memory

;00200  0326			NUM_BYTES,		! Adr. of longword containig size in bytes

;00300  0327			BLK_ADR_ADR)		! Adr. of longword containing adr. of block

;00400  0328			=

;00500  0329	

;00600  0330	!++

;00700  0331	!  FUNCTIONAL DESCRIPTION:

;00800  0332	!  

;00900  0333	!       Deallocates  n  virtually  contiguous  bytes  starting   at   the

;01000  0334	!       specified   virtual   address.   The  number  of  bytes  actually

;01100  0335	!       allocated is rouned up so that the smallest number of whole  quad

;01200  0336	!       words  are  de-allocated.  Numerous error checks are made to make

;01300  0337	!       sure that the block being returned is a legimate free area.

;01400  0338	!  

;01500  0339	!  CALLING SEQUENCE:

;01600  0340	!  

;01700  0341	!       CALL LIB$FREE_VM(num_bytes.rlu.r, base_adr.ra.r)

;01800  0342	!  

;01900  0343	!  INPUT PARAMETERS:

;02000  0344	!  

;02100  0345	!       num_bytes is  the  address  of  an  unsigned   longword   integer

;02200  0346	!                 specifying  the number of virtually contiguous bytes to

;02300  0347	!                 be deallocated.

;02400  0348	!  

;02500  0349	!       base_adr  is the address of a longword containing the address  of

;02600  0350	!                 the first byte to be deallocated.

;02700  0351	!  

;02800  0352	!  OUTPUT PARAMETERS:

;02900  0353	!  

;03000  0354	!  None.

;03100  0355	!  

;03200  0356	!  IMPLICIT INPUTS

;03300  0357	!  

;03400  0358	!  None.

;03500  0359	!  

;03600  0360	!  IMPLICIT OUTPUTS

;03700  0361	!  

;03800  0362	!       The pages are deallocated by calling $DEALTVA.   Then  the  pages

;03900  0363	!       are  marked  as  available  in  the  OWN  storage  maintained  by

;04000  0364	!       LIB$GET_VM.

;04100  0365	!  

;04200  0366	!  COMPLETION STATUS:

;04300  0367	!  

;04400  0368	!       SS$_NORMAL indicates normal successful completion.

;04500  0369	!       LIB$_BADBLOADR indicates BAD BLOCK ADDRESS

;04600  0370	!  

;04700  0371	!  SIDE EFFECTS:

;04800  0372	!     PUTS the indicated block back on the image free storage list.

;04900  0373	!--

;05000  0374	

;05100  0375	    BEGIN

;05200  0376	    LOCAL

;05300  0377		L_BLK_SIZE;

;05400  0378	

;05500  0379	    !+



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 5-1

;

;05600  0380	    ! Round up size to be a multiple of quadwords

;05700  0381	    !-

;05800  0382	

;05900  0383	    L_BLK_SIZE = (..NUM_BYTES + 7) AND ( NOT 7);

;06000  0384	

;06100  0385	    !+

;06200  0386	    ! Perform various checks for the validity of the request.

;06300  0387	    !-

;06400  0388	

;06500  0389	    IF .L_BLK_SIZE EQL 0 OR

;06600  0390		.L_BLK_SIZE GTRU .MAXSIZE OR

;06700  0391		(..BLK_ADR_ADR + .L_BLK_SIZE) GTRU K_VM_MAX_ADR OR

;06800  0392		..BLK_ADR_ADR LSSU .MINADDRESS

;06900  0393	    THEN

;07000  0394		RETURN LIB$_BADBLOADR

;07100  0395	    ELSE

;07200  0396		RETURN DEALLOCATE (.L_BLK_SIZE ,..BLK_ADR_ADR ,Q_LIST_HEAD)

;07300  0397	    END;











					 0004 000D1 	    .ENTRY  LIB$FREE_VM, Save R2				      ; 0325

		         52 00000000'  EF  9E 000D3 	    MOVAB   MAXSIZE, R2						      ;

	   50 	    04   BC	       07  C1 000DA 	    ADDL3   #7, @NUM_BYTES, R0					      ; 0383

	   51 	         50 	       07  CB 000DF 	    BICL3   #7, R0, L_BLK_SIZE					      ;

				       1A  13 000E3 	    BEQL    1$							      ; 0389

		         62 	       51  D1 000E5 	    CMPL    L_BLK_SIZE, MAXSIZE					      ; 0390

				       15  1A 000E8 	    BGTRU   1$							      ;

	   50 	    08   BC	       51  C1 000EA 	    ADDL3   L_BLK_SIZE, @BLK_ADR_ADR, R0			      ; 0391

	      40000000   8F	       50  D1 000EF 	    CMPL    R0, #1073741824					      ;

				       07  1A 000F6 	    BGTRU   1$							      ;

		    FC   A2	  08   BC  D1 000F8 	    CMPL    @BLK_ADR_ADR, MINADDRESS				      ; 0392

				       08  1E 000FD 	    BGEQU   2$							      ;

		         50 00000000G  8F  D0 000FF 1$:     MOVL    #LIB$_BADBLOADR, R0					      ; 0394

					   04 00106 	    RET     							      ;

				  10   A2  9F 00107 2$:     PUSHAB  Q_LIST_HEAD						      ; 0396

				  08   BC  DD 0010A 	    PUSHL   @BLK_ADR_ADR					      ;

				       51  DD 0010D 	    PUSHL   L_BLK_SIZE						      ;

		  0000V  CF	       03  FB 0010F 	    CALLS   #3, DEALLOCATE					      ;

					   04 00114 	    RET     							      ; 0325



; Routine Size:  68 bytes







; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 6

;

;00100  0398	ROUTINE DEALLOCATE(SIZE,ADDRESS,LISTHEAD) =

;00200  0399	!

;00300  0400	!	ROUTINE TO PUT A BLOCK ONTO A LIST OF FREE BLOCKS,

;00400  0401	!	WITH MAXIMAL COMPACTION

;00500  0402	!

;00600  0403	BEGIN

;00700  0404	LASTBLOCK = .LISTHEAD;				! PREVIOUS BLOCK INITIALLY THE LISTHEAD

;00800  0405	NEWBLOCK = .ADDRESS;				! CURRENT BLOCK IS TO BE INSERTED

;00900  0406	!

;01000  0407	WHILE (NEXTBLOCK = .LASTBLOCK[0])NEQ 0 DO	! FOLLOW DOWN FREE LIST TILL

;01100  0408	BEGIN						! THE END, OR TILL WE REACH

;01200  0409	IF NEWBLOCK[0] LEQU NEXTBLOCK[0]

;01300  0410	THEN

;01400  0411		BEGIN					! THE POSITION FOR INSERTION.

;01500  0412		IF NEWBLOCK[0]+.SIZE EQL NEXTBLOCK[0]

;01600  0413		THEN

;01700  0414			BEGIN				! HERE WE COMPACT WITH NEXT BLOCK

;01800  0415			NEWBLOCK[0] = .NEXTBLOCK[0];

;01900  0416			NEWBLOCK[1] = .NEXTBLOCK[1]+.SIZE;

;02000  0417			END

;02100  0418		ELSE

;02200  0419			BEGIN

;02300  0420			IF NEWBLOCK[0] + .SIZE GTRU NEXTBLOCK[0] ! IF THE BLOCK TO DEALLOCATE

;02400  0421			THEN

;02500  0422			    RETURN LIB$_BADBLOADR;		! BAD BLOCK ADDRESS code

;02600  0423			NEWBLOCK[0] = NEXTBLOCK[0];		! ELSE SET POINTER AND SIZE SINCE NO

;02700  0424			NEWBLOCK[1] = .SIZE;			! FORWARD COMPACTION NEEDED

;02800  0425			END;

;02900  0426		IF NEWBLOCK[0] EQL LASTBLOCK[0]+.LASTBLOCK[1]

;03000  0427		THEN

;03100  0428			BEGIN					! HERE WE COMPACT WITH PREVIOUS

;03200  0429			LASTBLOCK[0] = .NEWBLOCK[0];		! BLOCK

;03300  0430			LASTBLOCK[1] = .NEWBLOCK[1]+.LASTBLOCK[1];

;03400  0431			END

;03500  0432		ELSE						! NO BACKWARD COMPACTION BUT...

;03600  0433			BEGIN					! MUST CHECK THAT BLOCK TO

;03700  0434			IF NEWBLOCK[0] LSSU LASTBLOCK[0] + .LASTBLOCK[1]

;03800  0435								! DEALLOCATE IS NOT PARTIALLY IN

;03900  0436			THEN

;04000  0437			    RETURN LIB$_BADBLOADR;		! PREVIOUS HOLE __ FAILURE IF SO

;04100  0438			LASTBLOCK[0] = NEWBLOCK[0];	! IF OK PREVIOUS POINTS TO NEW ONE.

;04200  0439			END;				! AND WE ARE DONE COMPACTING

;04300  0440		RETURN SS$_NORMAL;				! SO RETURN SUCCESS.

;04400  0441		END

;04500  0442	ELSE

;04600  0443		LASTBLOCK = NEXTBLOCK[0];		! NOT THERE YET SO LAST BLOCK IS ONE JUST TESTED

;04700  0444	END;						! OF WHILE LOOP

;04800  0445	!

;04900  0446	! THE BLOCK TO DEALLOCATE IS BEYOND LAST HOLE

;05000  0447	!

;05100  0448	IF NEWBLOCK[0] LSSU LASTBLOCK[0] + .LASTBLOCK[1]	! BUT IF IT STARTS WITHIN

;05200  0449	THEN

;05300  0450	    RETURN LIB$_BADBLOADR				! LAST HOLE _ FAIL IT

;05400  0451	ELSE

;05500  0452		BEGIN						! OTHERWISE CHECK FOR COMPACTION



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 6-1

;

;05600  0453		IF NEWBLOCK[0] EQL LASTBLOCK[0] + .LASTBLOCK[1]	! WITH LAST HOLE

;05700  0454		THEN LASTBLOCK[1] = .LASTBLOCK[1] + .SIZE	! AND ADD IN SIZE IF REQUIRED

;05800  0455		ELSE

;05900  0456			BEGIN				! OTHERWISE JUST

;06000  0457			NEWBLOCK[0] = 0;		! PUT ON END OF FREE LIST.

;06100  0458			NEWBLOCK[1] =.SIZE;

;06200  0459			LASTBLOCK[0] = NEWBLOCK[0];

;06300  0460			END;				! AND ALL DONE

;06400  0461		RETURN SS$_NORMAL;			! SO RETURN SUCCESS

;06500  0462		END;

;06600  0463	END;			! OF ROUTINE











					 001C 00115 DEALLOCATE:

							    .WORD   Save R2,R3,R4					      ; 0398

		         54 00000000'  EF  9E 00117 	    MOVAB   LASTBLOCK, R4					      ;

		         64 	  0C   AC  D0 0011E 	    MOVL    LISTHEAD, LASTBLOCK					      ; 0404

		    F8   A4	  08   AC  D0 00122 	    MOVL    ADDRESS, NEWBLOCK					      ; 0405

		         51 	  F8   A4  D0 00127 	    MOVL    NEWBLOCK, R1					      ; 0409

		         50 	       64  D0 0012B 1$:     MOVL    LASTBLOCK, R0					      ; 0407

		    FC   A4	       60  D0 0012E 	    MOVL    (R0), NEXTBLOCK					      ;

				       4C  13 00132 	    BEQL    6$							      ;

		         52 	  FC   A4  D0 00134 	    MOVL    NEXTBLOCK, R2					      ; 0409

		         52 	       51  D1 00138 	    CMPL    R1, R2						      ;

				       3E  1A 0013B 	    BGTRU   5$							      ;

	   53 	         51 	  04   AC  C1 0013D 	    ADDL3   SIZE, R1, R3					      ; 0412

		         52 	       53  D1 00142 	    CMPL    R3, R2						      ;

				       0C  12 00145 	    BNEQ    2$							      ;

		         61 	       62  D0 00147 	    MOVL    (R2), (R1)						      ; 0415

      04   A1	    04   A2	  04   AC  C1 0014A 	    ADDL3   SIZE, 4(R2), 4(R1)					      ; 0416

				       0D  11 00151 	    BRB     3$							      ; 0412

		         52 	       53  D1 00153 2$:     CMPL    R3, R2						      ; 0420

				       35  1A 00156 	    BGTRU   7$							      ;

		         61 	       52  D0 00158 	    MOVL    R2, (R1)						      ; 0423

		    04   A1	  04   AC  D0 0015B 	    MOVL    SIZE, 4(R1)						      ; 0424

	   52 	         50 	  04   A0  C1 00160 3$:     ADDL3   4(R0), R0, R2					      ; 0426

		         52 	       51  D1 00165 	    CMPL    R1, R2						      ;

				       0A  12 00168 	    BNEQ    4$							      ;

		         60 	       61  D0 0016A 	    MOVL    (R1), (R0)						      ; 0429

		    04   A0	  04   A1  C0 0016D 	    ADDL2   4(R1), 4(R0)					      ; 0430

				       37  11 00172 	    BRB     11$							      ; 0426

		         52 	       51  D1 00174 4$:     CMPL    R1, R2						      ; 0434

				       2F  1E 00177 	    BGEQU   10$							      ;

				       12  11 00179 	    BRB     7$							      ; 0437

		         64 	       52  D0 0017B 5$:     MOVL    R2, LASTBLOCK					      ; 0443

				       AB  11 0017E 	    BRB     1$							      ; 0407

		         50 	       64  D0 00180 6$:     MOVL    LASTBLOCK, R0					      ; 0448

	   52 	         50 	  04   A0  C1 00183 	    ADDL3   4(R0), R0, R2					      ;

		         52 	       51  D1 00188 	    CMPL    R1, R2						      ;

				       08  1E 0018B 	    BGEQU   8$							      ;

		         50 00000000G  8F  D0 0018D 7$:     MOVL    #LIB$_BADBLOADR, R0					      ; 0450

					   04 00194 	    RET     							      ;



; Bliss-32 10.1-416	Monday 21-AUG-1978 19:36:32	DBB3:[RTL.SRC]LVM.B32;6						Page 6-2

;

		         52 	       51  D1 00195 8$:     CMPL    R1, R2						      ; 0453

				       07  12 00198 	    BNEQ    9$							      ;

		    04   A0	  04   AC  C0 0019A 	    ADDL2   SIZE, 4(R0)						      ; 0454

				       0A  11 0019F 	    BRB     11$							      ; 0453

				       61  D4 001A1 9$:     CLRL    (R1)						      ; 0457

		    04   A1	  04   AC  D0 001A3 	    MOVL    SIZE, 4(R1)						      ; 0458

		         60 	       51  D0 001A8 10$:    MOVL    R1, (R0)						      ; 0459

		         50 	       00G 9A 001AB 11$:    MOVZBL  S^SS$_NORMAL, R0					      ; 0461

					   04 001AE 	    RET     							      ; 0398



; Routine Size:  154 bytes





;06700  0464	END ELUDOM		! OF MODULE













;				       PSECT SUMMARY

;

;	Name		 Bytes			       Attributes

;

;  LIB$DATA       	    28    WRT,  RD ,NOEXE,NOSHR,  LCL,  REL,  CON,  PIC,ALIGN(2)

;  LIB$CODE       	   431  NOWRT,  RD ,  EXE,  SHR,  LCL,  REL,  CON,  PIC,ALIGN(2)











; Size:		431 code + 28 data bytes

; Run Time:	00:09.2

; Elapsed Time:	00:24.4

; Memory Used:	74 pages

; Compilation Complete

