Google
 

Trailing-Edge - PDP-10 Archives - bb-d549g-sb - pfh.mac
There are no other files named pfh.mac in the archive.
	TITLE	PFH - PAGE FAULT HANDLER
	SUBTTL	T WACHS /JT/TW 30 JAN 79

;COPYRIGHT (C) 1974,1979 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;
;
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
;ONLY  IN  ACCORDANCE  WITH  THE  TERMS  OF  SUCH LICENSE AND WITH THE
;INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE OR ANY  OTHER
;COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
;OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF THE  SOFTWARE  IS  HEREBY
;TRANSFERRED.
;
;THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT  NOTICE
;AND  SHOULD  NOT  BE  CONSTRUED  AS A COMMITMENT BY DIGITAL EQUIPMENT
;CORPORATION.
;
;DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY  OF  ITS
;SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.

	PFHWHO==0	;LAST MODIFIER
	PFHVER==2	;MAJOR VERSION
	PFHMIN==0	;MINOR VERSION
	PFHEDT==3	;EDIT LEVEL

	PFHVER==BYTE(3)PFHWHO(9)PFHVER(6)PFHMIN(18)PFHEDT
	LOC	<.JBVER==137>
	EXP	PFHVER
	RELOC

;REVISION HISTORY
;
;1	FIX SOME EFFICIENCY PROBLEMS.  SPECIFICALLY, ON INITIALIZING THE PFH,
;	IF PAGE 776 CAN NOT BE CREATED DUE TO LACK OF CORE, ATTEMPT TO
;	PAGE OUT A RANDOM USER PAGE TO MAKE ROOM.  AND WHEN REJECTING
;	A PAGE FOR PAGING OUT, PUT THAT PAGE BACK ON THE END OF THE FIFO
;	LIST INSTEAD OF FORGETTING IT.  ALSO ADD SOME SYMBOLS AND VERSION.

;2	THE MONITOR WILL NOW HAND US THE BASE ADDRESS OF THE USER'S PSI INTERRUPT
;	VECTOR AS THE FIFTH ARGUMENT TO THE MONITOR PFH CALL.  USE THIS
;	TO AVOID PAGING OUT THE USERS PSI VECTORS

;3	MAKE PFH.MAC WHICH IS LOADED AS AN EXE FILE BY LINK AND "MERGED"
;	INTO THE USERS ADDRESS SPACE BY THE 7.01 MONITOR.
;	ELIMINATE MAKPFH. USE .PSECT TO FACILITATE THIS.
;PAGE. UUO DEF'S

	.PAGIO==0	;SWAP A PAGE IN OR OUT
		;BIT 0		;0=SWAP IN, 1=SWAP OUT
		;BIT 1		;0=SWAP TO DRUM, 1=SWAP TO DISK
		;BIT 2-26	;0
		;BIT 27-35	;PAGE NUMBER
	.PAGCD==1	;CREATE OR DESTROY A PAGE
		;BIT 0		;0=CREATE, 1=DESTROY
		;BIT 1		;0=CREATE IN WS, 1=CREATE ON DSK
		;BIT 2-26	;0
		;BIT 27-35	;PAGE NUMBER
	.PAGEM==2	;MOVE OR EXCHANGE PAGE
		;BIT 0		;0=MOVE PAGE, 1=EXCHANGE PAGE
		;BIT 1-8	;0
		;BIT 9-17	;SOURCE PAGE LOCATION
		;BIT 27-35	;DESTINATION PAGE LOCATION
	.PAGAA==3	;SET OR CLEAR ACCESS-ALLOWED
		;BIT 0		;0=CLEAR BIT, 1=SET BIT
		;BIT 1-26	;0
		;BIT 27-35	;PAGE NUMBER
	.PAGWS==4	;RETURN BIT MAP OF WORKING SET
	.PAGGA==5	;RETURN BIT MAP OF ACCESS-ALLOWED
	.PAGCA==6	;DETERMINE ACCESS FOR GIVEN PAGE
		PA.GNE==1B0	;PAGE DOES NOT EXIST
		PA.GWR==1B1	;PAGE IS WRITABLE
		PA.GRD==1B2	;PAGE IS READABLE
		PA.GAA==1B3	;PAGE IS ACCESSIBLE
		PA.GAZ==1B4	;PAGE IS ALLOCATED BUT ZERO
		PA.GCP==1B5	;PAGE CANNOT BE PAGED OUT
		PA.GPO==1B6	;PAGE IS PAGED OUT
	.PAGCH==7	;CREATE HIGH SEG

;ERROR RETURNS
	PAGUF%==1	;UNIMPLEMENTED FUNCTION
	PAGIA%==2	;ILLEGAL ARG
	PAGIP%==3	;ILLEGAL PAGE NUMBER
	PAGMF%==4	;PAGE DOES NOT EXIST
	PAGMI%==5	;PAGE NOT IN CORE
	PAGCI%==6	;PAGE IN CORE
	PAGSH%==7	;PAGE IN SHARABLE HI SEG
	PAGIO%==10	;I/O ERROR
	PAGNS%==11	;NO SWAPPING SPACE
	PAGLE%==12	;CORE LIMIT EXCEEDED
	PAGIL%==13	;LOCKED
	PAGNX%==14	;VIRTUAL MEMORY LIMIT ZERO

;PAGE FAULT WORD
	PF.HCB==1B0	;1 IF WS CHANGED BY OTHER THAN PFH
	;BIT 1-17 IS PF.HPN -- PAGE CAUSING FAULT
	;BIT 18-35 IS PF.HFC -- TYPE OF PAGE FAULT

;GETTABS
	.GTSWP==7	;SWAPPING PARAMETERS
	.GTCVL==102	;LH HAS VIRTUAL PAGE LIMIT, RH HAS PHYSICAL LIMIT

;SETUUO ARG
	.STTVM==26	;TIME BETWEEN PAGE FAULT TRAPS IN MS
ADR:
	.PSECT	PFH,777000
PFH:	JRST	FIRST		;ENTER HERE
PC:	0
PAGE:	0
TIME:	0
RATE:	0
PSIV:	0			;[2] BYTE (9)HIGH VECTOR(9)0(18)BASE ADDR
	BLOCK	3		;FOR FUTURE EXPANSION

FAULT:	DMOVEM	1,SAVE1		;SAVE SOME ACS
	DMOVEM	3,SAVE3
	SETOM	OK		;INDICATE WE'RE OK SO FAR
PCA:	HRRZ	1,PC6		;PC AT FAULT
	CAIL	1,PFH		;FAULT INSIDE PFH?
	HALT	.		;SOMEBODY'S VERY CONFUSED!

PAGIN:	MOVEI	2,1		;WILL PROBABLY PAGE 1 PAGE
	SKIPN	3,FORCE		;IF NOT SIMULATING DUMP-MODE,
PAGEA:	HLRZ	3,PAGE6		;GET THE DESIRED PAGE
	TRZ	3,400000	;IGNORE WS HAS CHANGED BIT
PAGEB:	HRRZ	4,PAGE6		;REASON FOR THE FAULT
	XCT	TABLE(4)	;(USUALLY) SET UP 1 FOR THE UUO
	AOSG	FULFLG		;ARE WE AT OUR CORE LIMIT?
	PAGE.	1,		;NO, TRY TO PAGE IN THE PAGE
	  JRST	FULL		;CANT PAGE IT IN - REPLACE A PAGE
	SOJE	4,EXIT1		;GO AWAY IF ACCESS-ALLOWED FAULT
EXIT0:	JSR	ONFIFO		;[1] PUT NEW PAGE ON FIFO LIST
;**;[1] DELETED  	AOS	1,PNTRIN	;NO, SAVE PAGE IN FIFO LIST
;**;[1] DELETED  	MOVEM	3,(1)
;**;[1] DELETED  	CAML	1,DATEND	;AT TOP OF CIRCULAR BUFFER?
;**;[1] DELETED  	MOVE	1,DATPNM	;YES, RESET TO START
;**;[1] DELETED  	MOVEM	1,PNTRIN
	SKIPE	FORCE		;IF SIMULATING DUMP-MODE IO,
	JRST	TSTDM3		; CONTINUE

EXITER:	MOVE	1,TIME6		;GET TIME OF INTERRUPT
PCB:	MOVE	2,PC6		;AND PC
	DMOVEM	1,LSTIME	;SAVE LAST TIME AND PC OF FAULT
EXIT1:	DMOVE	1,SAVE1		;RESTORE ACS
	DMOVE	3,SAVE3
PCC:	JRSTF	@PC6		;AND EXIT

TABLE:	JRST	EXIT1		;AFTER A TIME INTERRUPT - ALL DONE
	SKIPA	1,[.PAGAA,,2]	;ACCESS ALLOWED FAULT
	MOVEI	1,.PAGEM		;PAGE EXISTS, BUT
	MOVEI	1,.PAGEM		; IS ON DISK
	JRST	TIMINT		;TIME INTERRUPT
	MOVE	1,[.PAGCD,,2]	;ALLOCATED BUT 0 PAGE,
	MOVE	1,[.PAGCD,,2]	; CREATE THE PAGE
;HERE TO PUT PAGE IN AC3 ON THE END OF THE FIFO LIST
;**;[1] ROUTINE MOVED HERE TO ALLOW CALLS FROM SEVERAL LOCATIONS

ONFIFO:	Z			;[1]
	AOS	1,PNTRIN	;[1] SAVE PAGE IN FIFO LIST
	MOVEM	3,(1)		;[1]
	CAML	1,DATEND	;[1] AT TOP OF CIRCULAR BUFFER?
	MOVE	1,DATPNM	;[1] YES, RESET TO START
	MOVEM	1,PNTRIN	;[1]
	JRST	@ONFIFO		;[1] RETURN
;ROUTINE TO TEST ALL PAGES OF THE WORKING SET
;ENTER 1=INSTRUCTION, LH(4)=0 OR SIGN BIT
;RETURNS +0 IF NO PAGES IN W/S SATISFY CONDITION OF INSTRUCTION
;RETURNS +1 IF SOME DO, WITH
;	1 = ADDR. OF DATA
;	3 = NO. PAGES THAT SATISFY
;	2,4 = N/A; CORRUPTED
;	DATA = UNTOUCHED
;	DATA+1 TO DATA(3) = PAGES THAT SATISFY
TSTALL:	0
	TLZN	4,200000	;3 ALREADY SET IF BIT 1=1
	SETZ	3,		;SET TO COUNT NUMBER OF PAGES
	MOVEM	1,WSTAB		;SAVE INSTR TO EXECUTE
	MOVE	1,[-775,,1]	;AOBJN WORD FOR WHOLE WORKING SET
	MOVSI	2,200000	;BIT TO TEST
	HRRI	4,0		;WORD IN WSTAB/AATAB TO TEST
TSTAL1:	SKIPN	WSTAB+1(4)	;WHOLE WORD 0?
	AOJA	4,TSTAL4
TSTAL2:	TDNE	2,WSTAB+1(4)	;PAGE IN WORKING SET?
	XCT	WSTAB		;YES, PAGE IN AATAB?
	JRST	TSTAL3		;WE'RE NOT INTERESTED
	HRRM	1,@DATSTO	;GOODNESS - SAVE PAGE NUMBER
	HLLM	4,@DATSTO	;SET SIGN BIT
	ADDI	3,1		;COUNT THE PAGE
	CAMLE	3,DATLEN	;FILLED THE BUFFER?
	JRST	TSTAL6		;YES, DONE
TSTAL3:	ROT	2,-1		;STEP TO NEXT BIT
	SKIPGE	2
	AOJA	4,TSTAL5
	AOBJN	1,TSTAL2	;GO TEST THE NEXT BIT
TSTAL4:	ADD	1,[43,,43]
TSTAL5:	AOBJN	1,TSTAL1
TSTAL6:	MOVE	1,DATPNT	;DONE - POINT 1 AT START OF TABLE
	SKIPE	3		;NON-SKIP IF DIDNT FIND ANYTHING
	AOS	TSTALL		;FOUND AT LEAST 1 - SKIP RETURN
	JRST	@TSTALL		;RETURN TO CALLER
TIMINT:	HLLZS	PAGE6		;SET SO AS NOT TO PAGE ANYTHING IN
	HRROM	4,FULFLG	;USER MIGHT HAVE RESET LIMIT, SO TRY AGAIN
				; TO PAGE IN A PAGE NEXT TIME
	HRROI	1,.GTCVL	;GET .PDCPL
	GETTAB	1,
	  HALT
	TRZ	1,400000	;CLEAR LIMIT BIT
	HRROI	2,.GTSWP
	GETTAB	2,		;GET JBTSWP
	  HALT
	ANDI	2,777		;CORE
	MOVE	4,2		;SAVE CURRENT CORE
	SUBI	2,-1(1)		;CORE - LIMIT
	TRNE	1,-1
	JUMPG	2,TIMIN1	;IF NOT OVER LIMIT,
;REALLY OUGHT TO TEST THE RATE HERE, NOT PAGE OUT ANYTHING IF THE 
; RATE IS FAIRLY HIGH (WILL WAIT TILL THAT NUMBER IS DETERMINED)
	MOVE	1,[.STTVM,,^D500]	;SINCE WE'RE NOT FIDDLING WITH ACCESS-ALLOWED
	SKIPN	TIMFST		; WE CAN AFFORD TIME INTERRUPTS EVERY 1/2 SECOND
	SETUUO	1,
	  JFCL
	SETOM	TIMFST	;INDICATE WE'RE IN "FAST" TIME-INTERRUPT MODE
	CAIG	4,5	;IF MORE THAN MINIMUM
	JRST	EXIT1		;LEAVE THINGS ALONE
	JRST	FULL2		;MORE - PAGE OUT A PAGE
;HERE WHEN OVER LIMIT (GUIDELINE SET)
TIMIN1:	HRRZM	2,@DATPNT	;SAVE EXCESS
	MOVEI	1,^D15		;GET WS TABLE AND AA TABLE
	MOVEM	1,WSTAB
	MOVEM	1,AATAB
	MOVE	1,[.PAGWS,,WSTAB]
	PAGE.	1,
	  HALT
	MOVE	1,[.PAGGA,,AATAB]
	PAGE.	1,
	  HALT
	MOVE	1,[TDNE 2,AATAB+1(4)] ;TEST FOR PAGES WITH AA OFF
	MOVSI	4,400000	;WILL PAGE OUT THOSE PAGES
	JSR	TSTALL
	  JRST	TIMIN2		;DIDNT FIND ANY, JUST CLEAR AA
	CAMGE	3,(1)		;FOUND MORE THAN EXCESS?
	MOVEM	3,(1)		;SAVE NUMBER
	PAGE.	1,		;PAGE OUT THE PAGES
	  JRST	EXIT1		;OOPS!
	MOVE	1,[.PAGWS,,WSTAB]	;GET WS TABLE AGAIN
	PAGE.	1,		;(AFTER HAVING PAGED OUT SOME PAGES)
	  HALT
TIMIN2:	MOVE	1,[TDNN 2,AATAB+1(4)]  ;NOW TEST FOR PAGES WITH ACCESS ALLOWED ON
	JSR	TSTALL
	  JRST	TIMIN6		;NONE????????!!!!!****
	MOVSI	4,200000
	IORM	4,DATA+1	;HAVE THE MONITOR SET AA BIT ON AA FAULT
	MOVEM	3,(1)		;SAVE NUMBER
	TLO	1,3		;SET TO CLEAR ACCESS-ALLOWED
	PAGE.	1,
	  JRST	EXIT1		;OOPS
	MOVE	1,[.STTVM,,^D1500]	;ACCESS-ALLOWED INTERRUPTS ARE SLOW,
	SKIPE	TIMFST		; SO ONLY CLEAR AA EVERY 1 1/2 SECS
	SETUUO	1,
	  JFCL
	SETZM	TIMFST		;INDICATE IN "SLOW" TIME-INT MODE
TIMIN6:	JRST	FIRST0		;RESET PAGES-IN-CORE LIST AND EXIT
;HERE IF COULDN'T PAGE IN A PAGE (PROBABLY CAUSE EXCEEDING LIMITS)
FULL:	SUBI	1,2
	CAMN	3,FORCE		;IF ERROR TRYING TO PAGE IN FOR TSTDMP,
	JUMPE	1,FULL5		;CREATE PAGE IF ILLEGAL PAGE ERROR (ALLOC BUT 0)
	SETZM	FULFLG		;SET FLAG ACCORDINGLY
TIMEA:	MOVE	1,TIME6		;GET TIME OF INT
	SUB	1,LSTIME	;MINUS TIME OF LAST INT
	SUBI	1,^D21		;IF WITHIN 1 TICK,
	MOVE	2,LSTPC		;AND THE PC IS SAME AS PREVIOUS
PCD:	CAMN	2,PC6
	JUMPLE	1,TSTDMP	;GO SEE IF WE'RE IN A LOOP
FULL1:	SETZM	RPTCNT		;CLEAR NUMBER OF RETRIES COUNT
FULL2:	AOS	1,PNTROU	;GET NEXT PAGE TO PAGE OUT (FIFO)
	CAMG	1,DATEND	;IF AT TOP OF BUFFER,
	JRST	FULL3
	AOS	1,OK
	CAILE	1,2		;IF DIDNT FIND ANYTHING TO PAGE OUT
	JRST	LOOP		; TWICE IN A ROW WE LOSE
	MOVE	1,DATPNT	;RESET TO THE BEGINNING
	MOVEM	1,PNTROU
FULL3:	SKIPN	2,(1)		;PAGE TO PAGE OUT
	JRST	FULL2
PCE:	HRRZ	1,PC6		;PC OF INTERRUPT
	LSH	1,-11		;CONVERT TO PAGE NUMBER
	CAMN	2,1		;IF NOT THE PAGE WITH THE PC
	 JRST	FULL6		;[1] PUT PAGE BACK ON FIFO
	HRRZ	1,.JBINT##	;SET UP PAGE FOR INTERCEPTS, SO WONT
	LSH	1,-11			; PAGE OUT THAT PAGE
	CAMN	2,1		;IS WANTED PAGE THE INTERRUPT PAGE?
				;[1] (DON'T PUT THIS ONE BACK ON FIFO)
	JRST	FULL2			; YES, DONT PAGE IT OUT
;**;[2] @PCE+7 1/2	DBR	SEPT 1976
PSIA:	HRRZ	1,PSIV6		;[2] GET RETURNED ADDR OF PSI VECTOR
	LSH	1,-11		;[2] MAKE INTO PAGE NUMBER
	CAIGE	2,(1)		;[2] MIGHT PRESENT PAGE FALL IN PSI RANGE?
	JRST	FULL3A		;[2] NO, IT IS IN A LESSER PAGE
	LDB	1,PSIB		;[2] GET HIGHEST VECTOR IN USE
	IMULI	1,4		;[2] MULTIPLY BY BLOCK SIZE TO MAKE OFFSET
PSIC:	ADD	1,PSIV6		;[2] ADD BASE
	LSH	1,-11		;[2] MAKE ADDRESS INTO PAGE NUMBER
	CAIG	2,(1)		;[2] CURRENT PAGE .LE. THIS ONE?
	JRST	FULL6		;[2] YES, THIS IS A PSI PAGE
FULL3A:	HRRZ	1,FORCE		;AND NOT THE PAGE IMMEDIATELY BEFORE THE
	CAIN	1,1(2)		; PAGE WE'RE TRYING TO PAGE IN FOR
	 JRST	FULL6		;[1] DUMP MODE -- PUT BACK ON FIFO
	HRRZ	1,EA		;IF DUMP MODE DON'T PAGE OUT UUO PAGE
	LSH	1,-11		;CONVERT TO APGE NUMBER
	CAMN	2,1		;SAME AS ONE WE'RE TRYING TO PAGE OUT
	 JRST	FULL6		;[1] YES, PUT BACK ON FIFO
	MOVEI	1,2		;PAGE IT OUT
	TLO	2,400000	;SET TO PAGE OUT THE PAGE
	CAILE	4,4		;IF ALLOCATED BUT ZERO,
	JRST	FULL4		;HAVE TO DO 2 UUOS
	MOVE	4,2		;PAGE IS ON DISK - REPLACE THE PAGE
	MOVEI	2,2		;PAGE OUT C(4), IN C(3)
	PAGE.	1,
	  JRST	[CAIN 1,12	;IF TOO BIG HE RESET HIS LIMIT
		JRST TIMINT	;SO RESET EVERYTHING
		JRST DONTNO]	;IT ISNT - WE'RE CONFUSED
	JRST	EXIT0		;WON - SAVE PAGE IN LIST AND EXIT
;HERE IF REQUIRED PAGE IS ALLOCATED BUT 0
FULL4:	SKIPA	3,2		;GET PAGE TO PAGE OUT

;HERE IF REQUIRED PAGE IS ALLOCATED BUT 0 WHILE SIMULATING DUMP-MODE IO
FULL5:	MOVE	1,[.PAGCD,,2]	;SET TO CREATE THE PAGE
	MOVEI	2,1		;1 PAGE TO DO
	PAGE.	1,
	  JRST	DONTNO		;OOPS - SOMEONE'S CONFUSED
	SKIPL	FULFLG		;IF CAME FROM TIMINT, LEAVE LARGE NEG. 
				; TO FORCE MONITOR TO TELL US WHEN FULL
	SETOM	FULFLG		;TELL PAGIN WE CAN CREATE THE PAGE NOW
	JRST	PAGIN		 ;AND GO TRY TO GET THE PAGE IN

;**;[1] , FULL5 + 7, DBR, JUNE 1976
;HERE TO PUT REJECTED PAGE BACK ON FIFO
FULL6:	EXCH	2,3		;[1] SAVE PAGE WE WANT IN, SET UP REJECT IN AC3
	JSR	ONFIFO		;[1] PUT BACK
	MOVE	3,2		;[1] RESTORE PAGE WE WANT IN
	JRST	FULL2		;[1] AND TRY AGAIN
;HERE IF WE GOT A FAULT FROM THE SAME PC AS BEFORE, WITHIN 1 TICK OF THE LAST
TSTDMP:	CAIE	4,3		;MONITOR DETECTED FAULT?
	JRST	FULL1		;NO, PROBABLY NOT A LOOP
	AOS	1,RPTCNT	;COUNT NUMBER OF TIMES WE'VE TRIED
	CAIGE	1,^D25		;LESS THAN 25 TIMES?
	JRST	FULL2		;YES, TRY TO REPLACE A PAGE
	SKIPE	FORCE		;PAGING IN A PAGE FOR TSTDMP?
	JRST	TSTDM3		;YES, CONTINUE
PCF:	HRRZ	1,PC6		;NO, WE'RE IN A LOOP, GET THE UUO
TSTDM1:	JSR	GETWRD
	MOVEM	1,EA		;SAVE EFFECTIVE ADR OF THE UUO
	HLLZ	2,@EA		;GET THE UUO
	LDB	1,[POINT 9,2,8];JUST OP CODE
	CAIN	1,256		;XCT INSTRUCTION?
	JRST	[HRRZ	1,@EA
		JRST	TSTDM1]
	CAIE	1,56		;IN, INPUT, OUT OR OUTPUT?
	CAIN	1,57
	JRST	TSTDM2		;YES
	CAIE	1,66
	CAIN	1,67
TSTDM2:	TLZA	2,777037	;YES, GET THE CHANNEL NUMBER
	JRST	LOOP		;NO - TELL USER HE LOST
	LDB	1,[POINT 4,2,12] ;CHAN NUMBER
	DEVCHR	1,		;GET CHARACTERISTICS
	TDO	2,[GETSTS 2]
	XCT	2		;GETSTS
	ANDI	2,17		;GET MODE
	TLNE	1,200000	;DISK?
	CAIGE	2,16		;YES, DUMP?
	JRST	LOOP		;NO, HE LOSES
TSTDM3:	SKIPE	1,IOWD		;FIRST TIME?
	JRST	TSTDM5		;NO, CONTINUE
	HRRZ	1,@EA		;YES, GET THE L(IOWD)
	JSR	TSTPAG		;CAN WE ACCESS THE PAGE?
	  JRST	TSTDM4		;YES
TSTD3A:	LSH	1,-11		;NO, GET THE PAGE NUMBER
	MOVEM	1,FORCE		;THAT'S THE PAGE WE WANT
	MOVE	3,1
	JRST	FULL2		;GO GET IT IN
TSTDM4:	JSR	GETWRD
	MOVE	1,(1)		;GET THE IOWD
TSTDM5:	ADDI	1,1		;POINT 1 AT THE FIRST WORD OF IOWD
	JSR	TSTPAG		;CAN WE ACCESS THE PAGE?
	  SOJA	1,TSTDM6	;YES
	SUBI	1,1		;NO, RESET 1 TO AN IOWD
	MOVEM	1,IOWD		;AND SAVE THE IOWD
	MOVEI	1,1(1)		;CAUSE ITS 1ST PAGE TO COME INTO CORE
	JRST	TSTD3A

TSTDM6:	MOVEI	2,1(1)		;1ST ADR OF IOWD
	TRO	2,777		;LAST ADR IN THIS PAGE
	SUBI	2,(1)		;NO OF WORDS IN FIRST PAGE
	MOVEI	3,1(1)		;STEP TO NEXT PAGE
TSTDM7:	ADDI	3,1000
	HRRZ	4,3		;GET ADDRESS IN 4
	LSH	4,-^D9		;TURN INTO PAGE NUMBER
	HRLI	4,.PAGCA	;AND CODE FOR ACCESSABILITY
	PAGE.	4,
	  HALT
	TLNN	4,(1B6)		;PAGED IN AND
	TLNN	4,(1B3)		;ACCESS ALLOWED ON (IN CORE?)
	JRST	TSTDM8		;NO
	ADDI	2,1000		;YES, BUMP THE WORDCOUNT
	JRST	TSTDM7		;AND TEST NEXT PAGE
TSTDM8:	TRZ	2,177
	JUMPN	2,TSTDM9	;IF NO PAGES IN CORE FOR THE LIST,
	HLRZ	2,1		;GET WORD COUNT
	CAILE	2,777600	;A WHOLE BLOCK?
	JRST	TSTD9A		;NO, THE WHOLE THING IS IN CORE
	MOVEM	1,IOWD
	MOVEI	1,1000(1)
	JRST	TSTD3A
TSTDM9:	MOVN	3,2		;-WDCNT
	HRLZS	3		;MAKE IT AN IOWD LH
	CAMGE	3,1		;HAVE ALL OF IOWD IN CORE?
TSTD9A:	SKIPA	3,1		;YES, USE IOWD
	HRR	3,1		;NO, USE PARTIAL IOWD
	MOVEM	3,IOWD
	HLL	3,@EA		;GET ORIGINAL UUO
	HRRI	3,IOWD		;WITH FAKED-UP IOWD
	XCT	3		;DO IT
	TDZA	4,4
	MOVEI	4,1		;IN OR OUT BADNESS
PCG:	ADDM	4,PC6		;SKIP 1 INSTR IF IN OR OUT SKIPPED
	HRLS	2		;DECREMENT ORIGINAL IOWD
	ADD	1,2		;BY AMOUNT WE DID
	SKIPN	4		;IF NO ERROR ON IN OR OUT,
	JUMPL	1,TSTDM5	;DO NEXT PART IF NOT DONE
	SETZM	IOWD		;THROUGH - RESET COUNTERS
	SETZM	FORCE
	SETZM	EA		;EFFECTIVE ADDRESS (FULL CHECKS IT)
PCH:	AOS	PC6		;START AFTER THE UUO
	JRST	EXITER		;EXIT BACK TO USER PROGRAM
;ROUTINE TO SEE IF A PAGE IS ACCESSABLE
;ENTER 1=ADDRESS, EXIT NON-SKIP IF YES, SKIP IF NO
;MAKES THE PAGE ACCESSABLE IF IT IS IN CORE, AA OFF
TSTPAG:	0
	HRRZ	2,1
	LSH	2,-11		;PAGE NUMBER
	MOVE	4,2		;SAVE FOR SET AA ON IF NEEDED
	HRLI	2,.PAGCA	;SET FOR PAGE.
	PAGE.	2,		;GET PAGE ACCESSABILITY
	  HALT
	TLNE	2,(PA.GPO)	;ON DISK?
TSTPG1:	AOSA	TSTPAG		;YES, SKIP
	TLNE	2,(PA.GAA)	;NO, ACCESS ALLOWED?
	JRST	@TSTPAG		;RETURN SKIP OR NON-SKIP
	MOVE	2,[.PAGAA,,3]	;IN CORE, ACCESS NOT ALLOWED
	MOVEI	3,1		;SET AA
	PAGE.	2,
	  JRST	TSTPG1		;OUGHT NOT HAPPEN
	JRST	@TSTPAG		;GIVE GOOD RETURN
LOOP:	OUTSTR	[ASCIZ	/
?PAGE FAULT LOOP. TRY LARGER LIMIT/]
	EXIT	1,
	SETZM	RPTCNT		;HE MIGHT HAVE INCREASED HIS LIMIT,
	HRROS	FULFLG
	SETOM	OK
	JRST	PAGIN		; SO TRY AGAIN

;ROUTINE TO COMPUTE EFFECTIVE ADR
GETWRD:	0
	JUMPE	1,@.-1		;IF AC  1 THROUGH 4,
	CAIG	1,4
	ADDI	1,SAVE1-1	;USE SAVED LOCATION
	JRST	@GETWRD
;HERE TO SEE WHAT'S IN CORE, SET UP LISTS ACCORDINGLY
DONTNO:	AOS	1,OK		;IF WE GOT HERE TWICE IN A ROW WITHOUT
	CAILE	1,2		; ACCOMPLISHING ANYTHING,
	JRST	LOOP		;WE'RE IN A LOOP - USER LOSES
	MOVEI	1,^D15		;OK, GET AABTAB AND WSBTAB
	HRROM	1,FULFLG
	MOVEM	1,WSTAB
	MOVEM	1,AATAB
	MOVE	1,[.PAGGA,,AATAB]
	PAGE.	1,
	  HALT		;OOPS!
	MOVE	1,[.PAGWS,,WSTAB]
	PAGE.	1,
	  HALT		;OOPS!
FIRST0:	MOVE	1,[TDNE 2,AATAB+1(4)] ;FIRST CHECK PAGES WITH ACCESS-ALLOWED OFF
	SETZ	4,
	JSR	TSTALL
	  JFCL
	TLO	4,200000	;DONT RESET 3, THE PAGE COUNTER
	MOVE	1,[TDNN 2,AATAB+1(4)] ;TEST PAGES WITH AA ON
	JSR	TSTALL
	  JFCL
	MOVE	4,DATPNT	;SET UP PAGE-OUT LIST
	ADDI	4,1		;1ST PAGE STORED IN DATA+1
	MOVEM	4,PNTROU
;**;[1] FIX AT FIRST0 + ^D11
	ADDI	4,-1(3)		;[1] POINT TO LAST PAGE IN LIST
	MOVEM	4,PNTRIN	;SET TO UPDATE FIFO LIST
	ADDI	4,1
	SETZM	(4)		;CLEAR REST OF BUFFER
	CAMGE	4,DATEND
	AOJA	4,.-2
	JRST	PAGIN		;PAGE IN A PAGE OR EXIT
LIT
DATPNT:	DATA
DATPNM:	DATA-1
DATSTO:	DATA+1(3)
DATLEN:	770
DATEND:	DATA+770
DATLST:	1
	DATPAG
NOPAGE:	1			;[1]
	400000,,1		;[1] BIT 0 = 1 TO PAGE OUT
JRSTFT:	JRST	FAULT
PSIB:	POINT	9,PSIV6,8	;[2] BYTE POINTER TO VECTOR FIELD
;HERE THE FIRST TIME
FIRST:	DMOVEM	1,SAVE1		;SAVE SOME ACS
	DMOVEM	3,SAVE3
	MOVE	4,JRSTFT
	MOVE	1,[.STTVM,,^D500]	;SET UP FOR TIME INTERRUPT EVERY
	SETUUO	1,		; 1/2 SECOND
	  JFCL
	SETOM	TIMFST		;INDICATE " FAST" TIME-INT MODE
TRY776:	MOVE	1,[.PAGCD,,DATLST]	;CREATE DATA PAGE FOR BUFFER
	PAGE.	1,
	  JRST	NO776		;CANT CREATE PAGE - USE A SMALL BUFFER
	MOVEM	4,PFH6		;RESET WHERE TO GO (SET UP FOR INTERRUPTS
	MOVEI	4,PFH6		; TO START OF PAGE 776 SINCE OTHERWISE THE MONITOR
	HRRM	4,.JBPFH##	; WONT KNOW HOW MUCH TO REMOVE WHEN DESTROYING SYS:PFH
	DMOVE	1,PC		;FIX UP FOR EXIT FROM PFH
	DMOVEM	1,PC6
	JRST	DONTNO		;SET UP WHAT'S IN CORE AND EXIT

NO776:	CAIE	1,PAGLE%	;[1] TOO MUCH IN CORE FOR DATA AREA?
	  JRST	NO776B		;[1] NOT THE CASE, USE SMALL BUFFER
NO776A:	MOVEI	1,NOPAGE		;[1] .PAGIO,,ADDR IN AC1
	PAGE.	1,		;[1] TO TRY TO PAGE OUT RANDOM PAGE
	 AOSA	1,NOPAGE+1	;[1] IT'S EFFORT THAT COUNTS, ANYWAY ...
	  JRST	TRY776		;[1] BUT NOTHING CAN BEAT SUCCESS!
	CAMLE	1,[400000,,DATPAG]	;[1] REACHED THE PFH YET?
	  JRST	NO776A		;[1] NO, KEEP TRYING TO PAGE ONE OUT
NO776B:	MOVEM	4,PFH		;RESET WHERE TO GO ON INTERUPT
	MOVEI	1,DATLST
	MOVEM	1,DATPNT	;SET UP TO USE A SMALL BUFFER SINCE
	SUBI	1,1		; WE CANT CREATE PAGE 776
	HRRM	1,DATPNM
	ADDI	1,2
	HRRM	1,DATSTO
	MOVEI	1,SMLEND
	MOVEM	1,DATEND
	MOVEI	1,BUFLEN-21
	MOVEM	1,DATLEN
	MOVEI	1,PC		;RESET TRAP LOCS FOR PAGE 777
	HRRM	1,PCA
	HRRM	1,PCB
	HRRM	1,PCC
	HRRM	1,PCD
	HRRM	1,PCE
	HRRM	1,PCF
	HRRM	1,PCG
	HRRM	1,PCH
	MOVEI	1,PAGE
	HRRM	1,PAGEA
	HRRM	1,PAGEB
	HRRM	1,TIMINT
	MOVEI	1,TIME
	HRRM	1,TIMEA
	HRRM	1,EXITER
;**;[2] @NO77B+26. 1/2	DBR	SEPT, 1976
	MOVEI	1,PSIV		;[2] PSI INFORMATION
	HRRM	1,PSIA		;[2]
	HRRM	1,PSIB		;[2]
	HRRM	1,PSIC		;[2]
	JRST	DONTNO
LIT
LEN==.-PFH
	BLOCK	15		;ROOM FOR A SMALL BUFFER
AATAB:	BLOCK	20		;NOTE THAT THE SMALL BUFFER WILL EXTEND HERE
WSTAB:	BLOCK	20
SMLEND==.-1
BUFLEN==.-DATLST
DATPAG==776			;PAGE FOR BUFFER
PFH6=DATPAG*1000
PC6=PFH6+1
PAGE6=PC6+1
TIME6=PAGE6+1
RATE6=TIME6+1
PSIV6=RATE6+1
DATA=DATPAG*1000+10
TIMFST:	0
FORCE:	BLOCK	1
LSTIME:	0
LSTPC:	0
OK:	0
RPTCNT:	0
FULFLG:	0
PNTRIN:	0
PNTROU:	0
IOWD:	BLOCK	2
EA:	BLOCK	1
SAVE1:	BLOCK	2
SAVE3:	BLOCK	2
	.ENDPS
	END