Google
 

Trailing-Edge - PDP-10 Archives - BB-L014E-BM - autopatch/formem.c05
There are no other files named formem.c05 in the archive.
 REP 2/1	;05C1
		TV	FORMEM	MEMORY MANAGEMENT,6(2033)
		SUBTTL	CHRIS SMITH/CKS

	;COPYRIGHT (C) 1981  BY  DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
 WIT
		TV	FORMEM	MEMORY MANAGEMENT,6(2121)
		SUBTTL	CHRIS SMITH/CKS/EGM/TGS

	;COPYRIGHT (C) 1981,1982  BY  DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
 INS 96/1	;05C2
	***** End V6 Development *****

	2034	DAW	27-Jan-82
		Allow overlaid programs to contain symbols.

	2052	EGM	27-Apr-82
		Add routine to cut back core for the block structured (OTS) core area.
		Cause %FREPGS to kill off pages returned for TOPS-10. Cause CREPGS for
		TOPS-10 to kill off any pages obtained for an incomplete request.
		Make KILPGS for TOPS-10 more forgiving of 'page non existent' errors.

	2053	EGM	23-Apr-82
		Improve paged core usage when getting additional pages by:
		1. Trying to get specific pages contiguous with the start of
		   the block list, and
		2. Considering any initial free block size when determining
		   the number of new pages to get.
		Also preserve the saved PC when linking in a new free block.

	2076	RJD	26-Aug-82
		Put FUNCT. functions 17 and 20 in conditional code for TOPS-10
		and TOPS-20.  For TOPS-10, set F.GPSI and F.RPSI equal to
		F.ILL.

	2106	TGS	13-Sep-82	20-17750
		Install trapping and ERR= handling for disk quota exceeded or
		disk full.  %FUNCT detects whether the routine address is that
		of FOROTS, and allows user to override it.

	2111	MRB	27-SEP-82	20-17959
		Correct edit 2034.

	2114	TGS	1-Oct-82	10-33104
		Edit 2034 contains an unneded HRRZ T1,.JBSYM.

	2121	RJD	28-Oct-82	20-18131
		Add two FUNCT. routines which mark and unmark the
		pages in the FOROTS memory management table.  The
		routines are called by FORSRT to let FOROTS know
		that the pages used by SORT are unavailable.

 REP 4/2	;05C3
		INTERN	%MEMINI
 WIT
		INTERN	%MEMINI,%FUNCX		;[2106]
 REP 8/2	;05C4

		EXTERN	%POPJ,%POPJ1,%POPJ2,%SAVE1,%SAVE2,%SAVE3,%SAVE4,%SAVE
		EXTERN	I.XSIR,%LEVTAB,%CHNTAB
 WIT
		INTERN	%MRKBL,%UNMBL			;[2121]

		EXTERN	%POPJ,%POPJ1,%POPJ2,%SAVE1,%SAVE2,%SAVE3,%SAVE4,%SAVE
		EXTERN	I.XSIR,%LEVTAB,%CHNTAB,%FCHTB ;[2106]
 REP 7/5	;05C5
		STKVAR	<SAVET,NP>	;ALLOCATE SPACE ON STACK
		MOVEM	T1,SAVET	;SAVE T1
		MOVEI	T1,2*HLEN+777(T1) ;ADD IN 2 HEADERS, ROUND UP TO PAGE BOUND
 WIT
		STKVAR	<SAVET,NP,SAVEP,> ;[2053] ALLOCATE SPACE ON STACK
		MOVEM	T1,SAVET	;SAVE T1
		HRRZ	T2,BEGPTR	;[2053] Get beginning of list
		SKIPN	(T2)		;[2053] EOL?
		JRST	GBANYP		;[2053] Yes - Get any pages, mark initial hole
		SKIPG	(T2)		;[2053] Is first block free?
		JRST	GBSSIZ		;[2053] No - use same size
		HLRZ	T3,HSIZE(T2)	;[2053] Free block size
		SUBI	T1,HLEN(T3)	;[2053] Reduce words needed
	GBSSIZ:	DMOVEM	P1,SAVEP	;[2053] Save P ACs
		MOVEI	P1,(T2)		;[2053] Free block address, always top of page
		MOVEI	P2,HLEN+777(T1)	;[2053] Size + header, rounded to page
		LSHC	P1,-^D9		;[2053] Last page number + 1/no. of pages
		SUBI	P1,(P2)		;[2053] First page number
		PUSHJ	P,CREPGS	;[2053] Try to get prefered pages
		  JRST	[DMOVE	P1,SAVEP ;[2053] No luck, restore P ACs
			 MOVE	T1,SAVET ;[2053] Get original size
			 JRST	GBANYP]	 ;[2053] Get any pages, mark hole
		MOVEI	T1,(P1)		;[2053] Got them, get first page number
		LSH	T1,^D9		;[2053] New free block address
		HRRZ	T4,BEGPTR	;[2053] First block contiguous with new one
		SKIPL	(T4)		;[2053] Is first block free?
		HRRZ	T4,HFLNK(T4)	;[2053] Yes - new core ends at successor
		DMOVE	P1,SAVEP	;[2053] Restore P ACs
		JRST	GBCONT		;[2053] Use prefered pages
	GBANYP:	MOVEI	T1,2*HLEN+777(T1) ;[2053] ADD 2 HEADERS, ROUND UP TO PAGE BOUND
 REP 20/5	;05C6
		CAIE	T2,(T3)		;NEW CORE CONTIGUOUS WITH OLD?
		  JRST	GBHOLE		;NO, GO HANDLE HOLE

		MOVEI	T4,(T2)		;COPY END ADDRESS OF NEW CORE
		SKIPLE	HFLNK(T4)	;CONTIGUOUS WITH A FREE BLOCK?
		  HRRZ	T4,HFLNK(T4)	;YES, CONSIDER NEW CORE ENDING AT END OF FREE BLOCK
		JRST	GBCONT		;CONTINUE BELOW

	GBHOLE:	MOVEI	T4,-HLEN(T2)	;MAKE HOLE LOOK LIKE PERMANENTLY ALLOCATED BLOCK
		HRROM	T3,HFLNK(T4)	;SET FORWARD LINK OF HOLE
 WIT
					;[2053]

	GBHOLE:	MOVEI	T4,-HLEN(T2)	;MAKE HOLE LOOK LIKE PERMANENTLY ALLOCATED BLOCK
		HRLI	T3,400000	;[2052] Unique hole marker for CBC function
		MOVEM	T3,HFLNK(T4)	;[2052] Set forward link of hole
 REP 35/5	;05C7
		HRRZM	T1,HBLNK(T4)	;POINT SUCCESSOR BACK TO NEW FREE BLOCK
 WIT
		HRRM	T1,HBLNK(T4)	;[2053] POINT SUCCESSOR BACK TO NEW FREE BLOCK
 INS 41/8	;05C8
	;[2121] MARK A BLOCK OF CORE ALLOCATED IN THE PAGE TABLE. THIS ROUTINE
	;[2121] IS CALLED WHENEVER A SHARABLE SEGMENT OF A LAYERED PRODUCT
	;[2121] IS LOADED VIA GET% (GETSEG) BY FOROTS.
	;[2121] ARGS:	T1 = FIRST PAGE TO MARK
	;[2121]	 	T2 = NUMBER OF PAGES

	%MRKBL:	PUSHJ	P,%SAVE4	;[2121] SAVE P1-P4
		DMOVE	P1,T1		;[2121] GET INTO THE CORRECT ACS
		MOVEI	T1,1		;[2121] GET PAGE-ALLOCATED BIT
		PUSHJ	P,DOPGS		;[2121] MOVE BIT THROUGH PAGE BIT MAP
		  TDNN	T1,PTAB(T2)	;[2121] SEE IF PAGES ARE ALL NOT ALLOCATED
		   SKIPA 		;[2121] ALL FREE, FINE
		JRST	%POPJ1		;[2121] SOME PAGE ALLOCATED, TRY AGAIN
		MOVEI	T1,3		;[2121] SET PAGE-ALLOCATED AND PAGE-EXIST
		PUSHJ	P,DOPGS		;[2121] MOVE THROUGH THE BIT MAP
		 IORM	T1,PTAB(T2)	;[2121] WITH THIS INSTRUCTION
		POPJ	P,		;[2121] SUCCESSFUL IN MARKING PAGES
		

	;[2121] UNMARK A BLOCK OF CORE IN THE PAGE TABLE. WHEN A LAYERED PRODUCT
	;[2121] DECIDES TO LEAVE (SUCH AS SORT), THE USER SHOULD BE ABLE TO GET
	;[2121] THE PAGES USED BY IT.

	%UNMBL:	PUSHJ	P,%SAVE4	;[2121] SAVE P1-P4
		DMOVE	P1,T1		;[2121] GET INTO THE CORRECT ACS
		MOVEI	T1,3		;[2121] GET PAGE-ALLOCATED BIT
		PUSHJ	P,DOPGS		;[2121] MOVE BIT THROUGH PAGE BIT MAP
		  TDNE	T1,PTAB(T2)	;[2121] SEE IF PAGES ARE ALL NOT ALLOCATED
		   SKIPA 		;[2121] ALL FREE, FINE
		JRST	%POPJ1		;[2121] SOME PAGE ALLOCATED, TRY AGAIN
		MOVEI	T1,3		;[2121] GET BOTH BITS
		PUSHJ	P,DOPGS		;[2121] MOVE T1 THROUGH BITS IN PTAB
		  ANDCAM T1,PTAB(T2)	;[2121] MARK PAGES FREE AND NONEXISTENT
		POPJ	P,		;[2121] DONE

 REP 44/8	;05C9
	;ON RETURN, PAGES ARE MARKED FREE IN BIT MAP
 WIT
	;[2052] On Return, pages are marked free in bit map for TOPS-20,
	;[2052] or have been removed and marked free/non existent for TOPS-10
 INS 50/8	;05C10
	IF20,<				;[2052]
 INS 54/8	;05C11
	>; End IF20			;[2052]

	IF10,<				;[2052]
		PJRST	KILPGS		;[2052] Remove the pages and update bit map
	>; End IF10			;[2052]
 REP 33/9	;05C12
		POPJ	P,		;COULDN'T CREATE THEM, ERROR RETURN
 WIT
		PJRST	KILPGS		;[2052] Can't get them all, kill any created
 REP 38/9	;05C13
		POPJ	P,		;DIDN'T WORK, ERROR RETURN
 WIT
		PJRST	KILPGS		;[2052] Can't get them all, kill any created
 REP 20/12	;05C14
	KILLP:	MOVE	T1,[-PLEN,,1]	;GET AOBJN POINTER TO PAGE. BLOCK
 WIT
	KILLP:	MOVE	T3,[-PLEN,,1]	;[2052] GET AOBJN POINTER TO PAGE. BLOCK
	KILLP0:	MOVE	T1,T3		;[2052] Get working AOBJN pointer
 REP 32/12	;05C15
	;	  ERR	(CDP,999,106,?,<Can't destroy page $O (PAGE. error $O)>,<T2,T1>)
		 $ECALL	CDP,%ABORT
		JUMPG	P2,KILLP	;IF MORE LEFT TO DO, DO THEM
 WIT
		  JRST	[CAIE	T1,PAGME%	;[2052] Page does not exist?
	;[2052]	  ERR	(CDP,999,106,?,<Can't destroy page $O (PAGE. error $O)>,<T2,T1>)
			 $ECALL	CDP,%ABORT	;[2052] No - some fatal error
			 HRRZ	T1,PBLK		;[2052] Get number of pages
			 CAIN	T1,1		;[2052] Doing 1 page at a time?
			 JRST	.+1		;[2052] Yes - just continue loop
						;[2052] Don't know which page had error
			 SUBI	P1,(T1)		;[2052] Back to first page
			 ADDI	P2,(T1)		;[2052] Reset count
			 MOVE	T3,[-1,,1]	;[2052] Use single step AOBJN ptr.
			 JRST	KILLP0]		;[2052] From this page on
		JUMPG	P2,KILLP0	;[2052] IF MORE LEFT TO DO, DO THEM
 INS 1/14	;05C16
	;[2052]Routine to trim block structured (OTS) core area
	;[2052]No arguments
	;[2052]
	;[2052] Trim back the block structured core area by removing all free pages
	;[2052] at the beginning of the list. Stop triming when an allocated block
	;[2052] or EOL is found, or after having split a block such that there are
	;[2052] no more free pages at the beginning of the list.

	PGTRIM:	STKVAR	<NXTBLK>	;[2052] Place to save pointer to next block
		HRRZ	T1,BEGPTR	;[2052] Start with first block
	PGTNXT:	SKIPG	T2,(T1)		;[2052] Is it free, and not EOL?
		JRST	PGTDON		;[2052] No - finished
		HLRZ	T3,HSIZE(T1)	;[2052] Get block size for later
		HLRZ	T4,(T2)		;[2052] Get allocated marker for next block
		CAIE	T4,400000	;[2052] Is it a hole?
		JRST	PGTNHL		;[2052] No - just look at this block
		ADDI	T3,HLEN		;[2052] Yes - absorb its length
		HRLM	T3,HSIZE(T1)	;[2052] Into current block
		HRRZ	T2,HFLNK(T2)	;[2052] Get its successor
		HRRM	T2,HFLNK(T1)	;[2052] Link hole out of the
		HRRM	T1,HBLNK(T2)	;[2052] Block structure entirely
		JRST	PGTPGS		;[2052] Go release some pages
	PGTNHL:	MOVEI	T4,HLEN(T3)	;[2052] Actual block size
		CAIGE	T4,^D512	;[2052] Have at least a page?
		JRST	PGTDON		;[2052] No - nothing more to do
		TRZ	T4,777000	;[2052] Excess words in next page
		JUMPE	T4,PGTNSU	;[2052] None - release some pages from 1 block
		CAIG	T4,HLEN		;[2052] Enough room for a block of 1 word?
		ADDI	T4,^D512	;[2052] No - one less page to free
		SUBI	T3,(T4)		;[2052] Reduce current block size
		JUMPLE	T3,PGTDON	;[2052] If no words left forget it
		HRLM	T3,HSIZE(T1)	;[2052] Save new block size
		ADDI	T3,HLEN(T1)	;[2052] Excess block address
		HRRZM	T2,HFLNK(T3)	;[2052] Setup forward link
		HRRM	T1,HBLNK(T3)	;[2052] Back link
		SUBI	T4,HLEN		;[2052] Actual size
		HRLM	T4,HSIZE(T3)	;[2052] Save away
		HRRM	T3,HFLNK(T1)	;[2052] Update predecessor pointer
		HRRM	T3,HBLNK(T2)	;[2052] And successor back pointer
	PGTNSU:	SETZ	T2,		;[2052] No successor block to consider
	PGTPGS:	HRRZM	T2,NXTBLK	;[2052] Save next block address
		HRRZ	T3,HBLNK(T1)	;[2052] Get block predecessor
		HRRZ	T4,HFLNK(T1)	;[2052] And successor
		HRRM	T4,HFLNK(T3)	;[2052] Link pages out of
		HRRM	T3,HBLNK(T4)	;[2052] Block structure
		CAMN	T1,FREPTR	;[2052] Giving up first free block?
		MOVEM	T4,FREPTR	;[2052] Yes - advance to next block
		HLRZ	T2,HSIZE(T1)	;[2052] Get size of block to free
		ADDI	T2,HLEN		;[2052] Actual size
		LSHC	T1,-^D9		;[2052] Page number/no. of pages
		PUSHJ	P,%FREPGS	;[2052] Free pages
		SKIPE	T1,NXTBLK	;[2052] Get next block to do if any
		JRST	PGTNXT		;[2052] Check further
	PGTDON:	UNSTK			;[2052] Free local storage
		POPJ	P,		;[2052] Done
 REP 43/14	;05C17
		MOVE	P1,JOBFF	;GET END+1 OF LOW SEGMENT
 WIT
		SETZM	SYMFP		;[2034] CLEAR "BETWEEN .JBFF AND .JBSYM" PNTR
		SKIPN	.JBSYM		;[2034] SYMBOL TABLE?
		 JRST	SETJFF		;[2034] NO
		HRRZ	T1,.JBSYM	;[2034] YES. GET ITS ADDR
		CAMG	T1,JOBFF	;[2034] HOLE BETWEEN JBFF AND JBSYM?
		 JRST	MRKSYM		;[2034] NO. JUST START MINILP ABOVE TABLE
					;[2034] [2114]
		HRL	T1,JOBFF	;[2034] GET FIRST FREE LOC IN HOLE
		MOVEM	T1,SYMFP	;[2034] SAVE FUTURE FREE LIST ENTRY
	MRKSYM:	HRRZ	T1,.JBSYM	;[2034] GET SYMBOL TABLE PNTR AGAIN
		HLRE	T2,.JBSYM	;[2034] CALC TOP OF TABLE+1
		SUB	T1,T2		;[2034] P1 NOW POINTS TO TOP OF SYMTAB+1
		CAMLE	T1,JOBFF	;[2034] IF GREATER THAN CURRENT .JBFF
		 MOVEM	T1,JOBFF	;[2034] SAVE AS NEW .JBFF
		HRL	T1,.JBSYM	;[2034] CREATE A SYMBOL TABLE FREE LIST ENTRY
		MOVEM	T1,SYMTP	;[2034] TO USE IF A CORE REQUEST FAILS
	SETJFF:	MOVE	P1,JOBFF	;[2034] GET END+1 OF LOW SEGMENT
 REP 7/15	;05C18
	MINILP:	CAILE	P1,760		;HAVE WE HIT TOP OF OUR CORE?
		  POPJ	P,

		HRRZ	T1,.JBHRL	;GET HS BREAK
 WIT
	MINILP:	CAIG	P1,760		;[2034] HAVE WE HIT TOP OF OUR CORE?
		 JRST	NOTTOP		;[2034] NO

		SKIPN	SYMFP		;[2034] ANY SPACE BETWEEN .JBFF AND .JBSYM?
		 POPJ	P,		;[2034] NO
		PUSHJ	P,LSINIT	;[2034] YES. MUST MARK A FREE BLOCK
		AOS	FLLEN		;[2034] MAKE AN ENTRY
		MOVE	T1,SYMFP	;[2034] GET THE FREE LIST ENTRY
		MOVEM	T1,(P3)		;[2034] STORE IT
		POPJ	P,		;[2034]

	NOTTOP:	HRRZ	T1,.JBHRL	;[2034] GET HS BREAK
 REP 22/15	;05C19
		  JRST	CHKSYM		;NO
 WIT
		  JRST	CHKDDT		;[2034] NO
 REP 26/15	;05C20
	CHKSYM:	HRRZ	T1,.JBSYM	;SYMBOL TABLE ADDR
		MOVEI	T2,(T1)		;COPY IT
		HLRE	T3,.JBSYM	;NEG COUNT
		SUB	T2,T3		;GET HIGH ADDR+1
		SOJL	T2,CHKDDT	;IF NEG, NO SYMBOLS
		PUSHJ	P,INUSCK	;PAGE IN SYMBOL TABLE?
		 AOJA	P1,MINILP	;YES, LEAVE IT
 WIT
					;[2034]
 INS 3/17	;05C21
	REQBOT:	BLOCK	1		;[2034] BOTTOM OF CORE REQUEST
	REQTOP:	BLOCK	1		;[2034] TOP+1 OF CORE REQUEST

	SYMFP:	BLOCK	1		;[2034] SPACE BETWEEN .JBFF AND SYMTAB
	SYMTP:	BLOCK	1		;[2034] BOTTOM,,TOP+1 OF SYMBOL TABLE
 INS 38/30	;05C22
		EXP	F.MPG		;[2121] 21 MARK PAGES AS BEING USED
		EXP	F.UPG		;[2121] 22 UNMARK PAGES
 REP 45/30	;05C23
		SKIPLE	T1,@FN(L)	;GET FUNCTION CODE
 WIT
	%FUNCX:	SKIPLE	T1,@FN(L)	;[2106] GET FUNCTION CODE
 REP 32/31	;05C24
		PUSHJ	P,LSGET		;ALLOCATE THE CORE
		  JRST	ERR1		;NOT ENOUGH MEMORY
		  JRST	ERR2		;ALREADY ALLOCATED
		JRST	OKRET		;ALLOCATED

 WIT
		DMOVEM	T1,REQBOT	;[2034] SAVE BOTTOM, TOP+1 OF REQUEST
		PUSHJ	P,LSGET		;[2034] ALLOCATE THE CORE
		  JRST	ERR1		;[2034] NOT ENOUGH MEMORY
		  JRST	TRYSYM		;[2034] ALREADY ALLOCATED. SEE IF SYMBOL TABLE
		JRST	OKRET		;[2034] ALLOCATED


	;[2034] HERE IF F.GAD CALL FAILS WITH CORE ALREADY ALLOCATED.
	;[2034] IF THE TOP OF THE CORE REQUEST IS WITHIN THE BOUNDS OF THE
	;[2034] ORIGINAL SYMBOL TABLE, RECORDED AS ALLOCATED, THE SYMBOL
	;[2034] TABLE IS INSERTED INTO THE FREE-CORE LIST. IT IS ASSUMED
	;[2034] THAT THE USER (OR OVRLAY) KNOWS WHAT HE/SHE/IT IS DOING...

	TRYSYM:	SKIPN	SYMTP		;[2034] ANY OLD SYMBOL TABLE?
		 JRST	ERR2		;[2034] NO
		HLRZ	T1,SYMTP	;[2034] GET BOTTOM OF OLD SYMBOL TABLE
		CAMLE	T1,REQTOP	;[2111][2034]IS IT BELOW TOP OF REQUESTED CORE?
		 JRST	ERR2		;[2034] NO
		HRRZ	T2,SYMTP	;[2034] GET TOP+1 OF OLD SYMBOL TABLE
		CAMGE	T2,REQTOP	;[2034] IS TOP+1 OF REQUESTED CORE WITHIN IT?
		 JRST	ERR2		;[2034] NO
		SKIPE	FLLEN		;[2034] ANY ENTRIES IN FREE-LIST YET?
		 JRST	INSSYM		;[2034] YES. GO INSERT THE SYMTAB ENTRY
		PUSHJ	P,LSINIT	;[2034] NO. CREATE A FREE LIST
		AOS	FLLEN		;[2034] INCR # ENTRIES
		MOVE	T1,SYMTP	;[2034] GET THE SYMBOL TABLE ENTRY
		MOVEM	T1,(P3)		;[2034] DROP IT INTO THE FREE LIST
		JRST	GADAGN		;[2034] GO TRY AGAIN

	INSSYM:	PUSHJ	P,LSFREE	;[2034] PUT THE SYMBOL TABLE IN THE FREE-LIST
		 $SNH			;[2111] BETTER BE A FREE LIST
	GADAGN:	SETZM	SYMTP		;[2034] DON'T TRY THIS AGAIN
		DMOVE	T1,REQBOT	;[2034] GET THE ORIGINAL CORE REQUEST PARAMS
		PUSHJ	P,LSGET		;[2034] TRY TO GET IT
		 JRST	ERR1		;[2034] MEMORY FULL
		 JRST	ERR2		;[2034] ALREADY ALLOCATED
		JRST	OKRET		;[2034] GOT IT!
 REP 235/31	;05C25
	;RETURNS STATUS 0 ALWAYS, WITH LOW SEG SHRUNK IF POSSIBLE
 WIT
	;[2052] Returns status 0 always, with low seg and OTS core shrunk if possible
 INS 239/31	;05C26
		PUSHJ	P,PGTRIM	;[2052] Trim OTS core size if possible
 REP 322/31	;05C27
	;OR MTOPR, FOR EXAMPLE).

 WIT
	;[2106] OR MTOPR, FOR EXAMPLE). IF FOROTS WAS THE PREVIOUS OWNER OF
	;[2106] THE CHANNEL (BY EVIDENCE OF THE %FCHTB ENTRY BEING IDENTICAL
	;[2106] TO THE %CHNTAB ENTRY), IT IS NOT CONSIDERED AN ERROR CONDITION.


	IF10,<				;[2076]
	F.GPSI==F.ILL			;[2076] TOPS-20 FUNCTION ONLY
	>				;[2076]

	IF20,<				;[2076]
 REP 330/31	;05C28
		SKIPE	%CHNTAB(T1)	;CHANNEL IN USE?
		  JRST	ERR1		;YES, ERROR
		SKIPLE	T2,@ARG2(L)	;GET PSI LEVEL
 WIT
		SKIPN	%CHNTAB(T1)	;[2106] CHANNEL IN USE?
		  JRST	GPNIU		;[2106] NO, OK
		CAME	T2,%FCHTB(T1)	;[2106] WAS FOROTS USING IT?
		  JRST	ERR1		;[2106] NO, GENUINE ERROR
	GPNIU:	SKIPLE	T2,@ARG2(L)	;[2106] GET PSI LEVEL
 REP 352/31	;05C29

 WIT
	>				;[2076]
 INS 367/31	;05C30
	IF10,<				;[2076]
	F.RPSI==F.ILL			;[2076] TOPS-20 FUNCITON ONLY
	>				;[2076]

	IF20,<				;[2076]
 REP 392/31	;05C31

 WIT
	>				;[2076]
	;[2121] FUNCTION 21:  MARK PAGES AS BEING UNAVAILABLE
	;[2121] 
	;[2121] ARG1:	ADDRESS OF WORD CONTAINING FIRST PAGE NUMBER TO MARK
	;[2121] ARG2:	ADDRESS OF WORD CONTAINING NUMBER OF PAGES TO MARK
	;[2121] 
	;[2121] RETURN STATUS 0 IF SUCCESSFUL IN MARKING ALL GIVEN PAGES
	;[2121] 	       	     1 IF ONE OR MORE PAGES ALREADY IN USE
	;[2121] 	             3 IF ILLEGAL ARGUMENT (BAD PAGE NUMBER OR COUNT)

	F.MPG:	PUSHJ	P,CHKPGA	;[2121] CHECK FOR LEGAL ARGUMENTS
		 JRST	ERR3		;[2121] BAD CALL
		PUSHJ	P,%MRKBL	;[2121] MOVE THROUGH THE BIT MAP
		 JRST	OKRET		;[2121] SUCCESSFUL RETURN
		 JRST	ERR1		;[2121] ONE OR MORE PAGES ALREADY IN USE

	;[2121] FUNCTION 22:  UNMARK PAGES PREVIOUSLY MARKED BY AN MPG AS FREE
	;[2121] 
	;[2121] ARG1:	ADDRESS OF WORD CONTAINING FIRST PAGE NUMBER TO UNMARK
	;[2121] ARG2:	ADDRESS OF WORD CONTAINING NUMBER OF PAGES TO UNMARK
	;[2121] 
	;[2121] RETURN STATUS 0 IF SUCCESSFUL IN UNMARKING ALL GIVEN PAGES
	;[2121] 	      1 IF ONE OR MORE PAGES WAS NOT IN USE
	;[2121] 	      3 IF ILLEGAL ARGUMENT (PAGE NUMBER OR COUNT)

	F.UPG:	PUSHJ	P,CHKPGA	;[2121] CHECK FOR LEGAL ARGUMENTS
		 JRST	ERR3		;[2121] BAD CALL
		PUSHJ	P,%UNMBL	;[2121] MOVE THROUGH THE BIT MAP
		 JRST	OKRET		;[2121] SUCCESSFUL RETURN
		 JRST	ERR1		;[2121] ONE OR MORE PAGES ALREADY IN USE

	CHKPGA:	SKIPG	T1,@ARG1(L)	;[2121] GET PAGE #
		 POPJ	P,		;[2121] BAD CALL
		CAILE	T1,777		;[2121] MUST BE A LOCAL PAGE ADDR
		 POPJ	P,		;[2121] BAD CALL
		SKIPG	T2,@ARG2(L)	;[2121] GET # PAGES
		 POPJ	P,		;[2121] BAD # PAGES
		MOVE	T3,T1		;[2121] CHECK TOTAL
		ADD	T3,T2		;[2121]
		CAILE	T3,1000		;[2121] TOP PAGE + 1 MUST BE .LE. 1000
		 POPJ	P,		;[2121] BAD CALL
		JRST	%POPJ1		;[2121]
 SUM 234124