	TITLE PAGEIMP - DEMAND PAGING ROUTINES FOR DATA

	SUBTTL W.D.HAY, UNIVERSITY OF EDINBURGH, MAY '74

	PAGED==1
	PAGVER==50
;V2 REORGANISED CALLING SEQUENCE TO ALLOW ARBITRARY LOWER BOUND
;V3 INTRODUCED ROUTINE FILL AND CALLS TO IT AS APPROPRIATE
;V4 SPEEDES UP INITIALISATION BY ONLY CALLING ALCOR. ONCE
;V5 INCLUDES LOCKING IN PAGE CODE.
;	EDIT 1 FIX HRRZ @IOPAG+1 TO BE MOVE. ALLOWS ADDRESSES > 256K
;V50	BUTCHERED VERSION OF V5 FOR IMP


	SEARCH IMPPRM
	;AC DEFINITIONS
	T0=0
	T1=1		;CURRENT PAGE NO
	T2=2		;OFFSET WITHIN PAGE
	T3=3		;POINTER TO DATA BASE
	T4=4		;IN-CORE PAGE NO
	T5=5		;MISCELLANEOUS
	T6=6		;UNUSED EXCEPT IN RANIO ROUTINES
	T7=7		;DO
	L=ARG1		;FIRST IMP ARGUMENT?
	P=17		;STACK

	;MACRO DEFINITIONS FOR DEFINING OFFSETS
;SUBSTITUE FORPRM MACROS

	DEFINE HELLO(NAME)
<	SIXBIT/NAME/
NAME::
>
	DEFINE GOODBYE
<	POPJ	P,
>
	DEFINE ZERO <A..==0>

	DEFINE OFF(SYMBOL)
	< SYMBOL=A..
	  A..=A..+1 >

	;DATA BASE DEFINITIONS
	SALL			;SUPRESS MACRO EXPANSION
	ZERO			;RESET OFFSET
	OFF (D.RAND)		;RANDOM ACCESS CHANNEL ETC.
	OFF (D.MAXP)		;LARGEST PAGE NO FOR SWAPPING PAGES
	OFF (D.MAXA)		;LARGEST IN-CORE PAGE NO

	OFF (D.NXTP)		;NEXT PAGE NO
	OFF (D.ICPT)		;CORRESPONDANCE TABLE FROM CORE TO VIRTUAL PAGE NO
	OFF (D.ICPA)		;ADDRESS OF IN-CORE PAGE
	OFF (D.NWOR)		;NO OF WORDS PER PAGE
	OFF (D.NWM1)		;NO OF WORDS -1 (USED FOR ROUNDING PURPOSES)
	OFF (D.RTAB)		;POINTER TO READ TABLE
	OFF (D.WTAB)		;POINTER TO WRITE TABLE

	DLEN=A..		;LENGTH OF TABLE

	;ARGUMENTS FOR IVALUE/ENTER

	ZERO			;OFFSET RESET
	OFF (S.IDBA)		;POINTER TO DATA BASE TABLE
	OFF (S.IADR)		;VIRTUAL ADDRESS
	OFF (S.IVAL)		;VALUE TO DEPOSIT (ENTER ONLY)

	;ARGUMENTS FOR PAGINI

	ZERO		;RESET OFFSET
	OFF (P.ADDR)	;ADDRESS OF BUFFER FOR WORKSPACE
	OFF (P.SIZE)	;SIZE OF BUFFER
	OFF (P.CHAN)	;MONITOR I/O CHANNEL

	OFF (P.LBND)	;LOWER BOUND
	OFF (P.UBND)	;UPPER BOUND
	OFF (P.NWIP)	;NUMBER OF WORDS IN PAGE
	OFF (P.NICP)	;NUMBER OF IN-CORE PAGES
	OFF (P.STRT)	;PAGING STRATEGY (UNUSED AT PRESENT)

	OFF (P.IDBA)	;ASSOCIATED VARIABLE
	OFF (P.IERR)	;ERROR VARIABLE




	;RANIO ARGUMENTS

	EXP	^D8	;8 ARGUMENTS FOR RANIO
RANARG:
.RFILE:	0		;FILE-ADDRESS WILL BE PATCHED
.RPJNO:	0		;PROJECT #
.RPGNO:	0		;PROGRAMMER #
.RNWIP:	0		;# OF WORDS IN PAGE
.RTNOP:	ARG	TNOP	;TOTAL NO OF PAGES
.RSUPR:	0		;SUPERSEED
.RIDBA:	0		;ASSOCIATED VAR
.RIERR:	0		;ERROR WORD



	;MACRO TO TRANSFER ARGUMENTS FROM PAGINI TO RANIO

	DEFINE XFR(X)
	< SALL
	MOVE 0,P.'X'(L)
	MOVEM	0,.R'X  >
	;LOCAL STORAGE FOR AC'S


	TEMP:	0
	TNOP:	0		;HOLDS TOTAL NO OF PAGES DURING PAGINI
	ADR:	0	;HOLDS ADDRESS DURING ALCOR SIMULATION
	COUNT:	0	;- # OF WORDS OF FREE STORE IN ALCOR SIMULATION

	PAGE
	SUBTTL TRACING MACROS ETC

	RPTRAC==400000		;TRACE PAGE CHANGES BIT
	RATRAC==200000		;TRACE ADDRESSE

	IFNDEF TRACEP,< TRACEP==0>
	IFNDEF TRACEA,< TRACEA==0>

	IFE TRACEP,<
	DEFINE $PTRCE (A,%B)  <>
	DEFINE $SKPPN (A)  <>
	DEFINE $SKPPF (A)  <>
	>

	IFE TRACEA,<
	DEFINE $ATRCE(A) <>
	DEFINE $SKPAN(A) <>
	DEFINE $SKPAF (A) <>
	>

	IFN TRACEP,<
	IF2,<PRINTX ASSEMBLING PAGE TRACING (USES FOROTS CHANNEL 20)>
	DEFINE $PTRCE (A,%B)
<	TLNN	T3,RPTRAC
	JRST	%B
	A
%B: >
	DEFINE $SKPPN (A)
<	TLNN	T3,RPTRAC
	A
>
	DEFINE $SKPPF (A)
<	TLNE	T3,RPTRAC
	A
>
>
	IFN TRACEA,<
	IF2,<PRINTX ASSEMBLING ADDRESS TRACING (USES FOROTS CHANNEL 16)>
	DEFINE $ATRCE (A,%B)
<	TLNN	T3,RATRAC
	JRST	%B
	A
%B:	>
	DEFINE $SKPAN (A)
<	TLNN	T3,RATRAC
	A
	>

	DEFINE $SKPAF (A)
	<TLNE	T3,RATRAC
	A
>>
	PAGE
	SUBTTL BASIC GET AND PUT ROUTINES

;	I=IVALUE(IDB,IADR)
;
;		RETURNS WORD STORED AT ADDRESS IADR IN PAGED DATA
;		SET IDB
;
	HELLO	(IVALUE)	;ENTRY SEQUENCE
	PUSHJ	P,IOPAG		;DO COMMON THINGS
	$ATRCE <	PUSH	P,L		;SAVE LINK
	MOVEI	L,T.ARG1	;SET POINTER
	PUSHJ	P,WTB.##
	MOVEI	L,T.ARG2
	PUSHJ	P,IOLST.##
	PUSHJ	P,FIN.
	POP	P,L		;RESTORE LINK
	>
	XCT	@D.RTAB(T3)	;DO THE PICK-UP
	$PTRCE <	HRRZ	T2,@D.RTAB(T3)
	AOS	-1(T2)
>
	MOVE	AC,0		;RETURN RESULT
BYEBYE:	GOODBYE			;AND EXIT

;
;	CALL ENTER(IDB,IADR,IDAT)
;
;		DEPOSITS IDAT AT LOC IADR IN IDB
;
	HELLO	(ENTER)
	PUSHJ	P,IOPAG		;DO THE COMMON STUFF
	MOVE	0,ARG3	;GET THE DATA
	XCT	@D.WTAB(T3)	;DO THE DEPOSIT
	$ATRCE <	PUSH	P,L
	MOVNS	T.ADDR
	MOVEI	L,T.ARG1
	PUSHJ	P,WTB.
	MOVEI	L,T.ARG2
	PUSHJ	P,IOLST.
	PUSHJ	P,FIN.##
	POP	P,L
>
	$PTRCE <	HRRZ	T2,@D.WTAB(T3)
	AOS	-2(T2)
>
	GOODBYE			; & RETURN

;	IOPAG SETS UP AC'S AS FOLLOWS
;
;	T1 - PAGE NO
;	T2 - OFFSET
;	T3 - POINTER TO DATA BASE
;
IOPAG:	MOVE	T3,ARG1	;GET POINTER
	MOVE	T1,ARG2	;**ED 1 AND ADDRESS
	$SKPAF <MOVEM T1,T.ADDR>
	ADD	T1,D.NWM1(T3)	;ROUND BLOCKS UP 1 AND OFFSET DOWN 1
	IDIV	T1,D.NWOR(T3)	;SPLIT INTO PAGE & OFFSET
	POPJ	P,		;& RETURN

	PAGE
	SUBTTL PAGE FAULT ROUTINES

WFAULT:	PUSHJ	P,GETPAG	;GET IN-CORE PAGE 
	HRLI	T4,(MOVE (T2))	;PATCH INSTRUCTION
	MOVEM	T4,@D.RTAB(T3)	;INTO READ TABLE
	HRLI	T4,(SETAM (T2)); AND INTO
	MOVEM	T4,@D.WTAB(T3)	;WRITE TABLE
	SOS	(P)		;SET UP SO THAT POPJ CAUASES
	POPJ	P,		;REEXECUTION OF THE XCT

RFAULT:	PUSHJ	P,GETPAG	;GET IN-CORE PAGE ADDRESS INTO T4
	HRLI	T4,(MOVE (T2))	;PATCH INSTRUCTION INTO 
	MOVEM	T4,@D.RTAB(T3)	;INTO WRITE TABLE
	MOVE	T4,[PUSHJ P,FWRITE] ;AND PATCH JUMP TO FIRST WRITE
	MOVEM	T4,@D.WTAB(T3)	;INT WRITE TABLE
MPOP:	SOS	(P)		;AND SET TO REEXECUTE THE XCT
	POPJ	P,

;	FWRITE IS CALLED ON THE FIRST WRITE TO A PAGE THAT WAS
;	BROUGHT INTO CORE ON A READ. IT ALLOWS THE PAGER TO FIND OUT
;	IF A WRITE HAS BEEN DONE, AND CONSEQUENTLY WHETHER IT NEEDS
;	PAGE OUT HTIS PAGE.

FWRITE:	MOVE	T4,@D.RTAB(T3)	;GET POINTER TO IN-CORE PAGE
	HRLI	T4,(SETAM (T2));PATCH THE INSTRUCTION
	MOVEM	T4,@D.WTAB(T3)	;INTO WRITE TABLE
	JRST	MPOP


	PAGE
	SUBTTL DISK PAGEING ROUTINE

GETPAG:	SOSG	T4,D.NXTP(T3)	;GET PAGE TO SWAP OUT
	MOVE	T4,D.MAXP(T3)	;IF 0 WRAP AROUND
	MOVEM	T4,D.NXTP(T3)	;
	MOVE	T6,@D.ICPA(T3)	;GET POINTER TO CORE BLOCK
	MOVEM	T6,TEMP		; & SAVE IT
	EXCH	T1,@D.ICPT(T3)	;PICK UP OLD PAGE NO-SAVE NEW ONE
	$PTRCE <	MOVEM	T1,OPAG
	PUSH	P,L
	JUMPLE	T1,GETP10
	HRRZ	L,@D.ICPA(T3)
	MOVE	T5,-1(L)
	MOVEM	T5,READS
	SETZM	-1(L)
	MOVE	T5,-2(L)
	MOVEM	T5,WRITES
	SETZM	-2(L)
GETP10:	MOVEI	L,F1000
	PUSHJ	P,OUT.##
	MOVEI	L,F2000
	PUSHJ	P,IOLST.##
	POP	P,L	>
	JUMPL	T1,REDPAG	;VIRGIN-DONT WRITE IT
	SKIPL	@D.WTAB(T3)	;EVER WRITTEN?
	JRST	DRWT		;NO-DONT WRITE IT OUT
	PUSHJ	P,RANWRT	;WRITE THE PAGE
DRWT:	MOVE	T6,[PUSHJ P,RFAULT] ; PATCH DISPATCH TO FAULT ROUTINE
	MOVEM	T6,@D.RTAB(T3)	;PATCH READ TABLE
	HRRI	T6,WFAULT	;WRITE FAULT
	MOVEM	T6,@D.WTAB(T3)	;PATCH WRITE TABLE
REDPAG:	SKIPGE	T1,@D.ICPT(T3)	;GET NEW PAGE NO
	JRST	GETEX		;DONT READ -VE PAGES
	SKIPGE	@D.RTAB(T3)	;HAS THIS PAGE EVER BEEN ALLOCATED ON DISK
	JRST	NVRALC		;NO-ZERO THE AREA
	PUSHJ	P,RANRED	;READ THE NEW PAGE
GETEX:	MOVE	T4,@D.ICPA(T3)	;GET THE ADDRESS OF THE PAGE
	POPJ	P,		; & RETURN

NVRALC:	MOVEI	T5,0		;PREPARE TO ZERO THE IN-CORE PAGE
	MOVE	T6,D.NWOR(T3)	;NO OF WORDS TO DO
	MOVE	T7,TEMP		;ADDRESS TO START THE ZERO
	PUSHJ	P,FILL		;DO IT
	JRST	GETEX		;AND DO THE RETURN STUFF


	PAGE
	SUBTTL INITIALISATION ROUTINES

PAGINI::
	MOVE	P.UBND(L)	;GET UPPER BOUND ON ADDRESS
	SUB	P.LBND(L)	;GET # OF WORDS + 1
	SOS	0		;# OF WORDS
	IDIV	P.NWIP(L)		;NO OF PAGES -1
	AOS	0		;# OF PAGES
	MOVEM	TNOP		;SAVE FOR LATER
	MOVE	T1,P.ADDR(L)	;BASE OF BUFFER
	MOVEM	T1,ADR		;SAVE FOR ALCOR
	MOVN	T1,P.SIZE(L)	;LENGTH OF BUFFER
	MOVEM	T1,COUNT
	MOVEI	T1,DLEN		;LENGTH OF DATA RECORD
	MOVEM	T1,TEMP
	PUSHJ	P,ALCOR		;GET IT
	MOVE	T3,0		;T3 POINTS TO DATA BASE RECORD
	MOVE	T1,P.NWIP(L)	;# OF WORDS IN A PAGE
	SUBI	T1,1		;
	LSH	T1,-7
	ADDI	T1,1
	MOVE	T2,P.CHAN(L)	;IMP CHANNEL NUMBER
	HRL	T2,DASQVEC##(T2);GET IMP SCB FOR STREAM
	HRR	T2,T1		;
	MOVEM	T2,D.RAND(T3)
	MOVE	0,P.NWIP(L)	;GET NO OF WORDS IN PAGE
	MOVEM	0,D.NWOR(T3)	;SAVE IN DATA BASE
	SUB	0,P.LBND(L)	;FOR PAGE / OFFSET ROUNDING
	MOVEM	0,D.NWM1(T3)	;SAVE IT
	MOVE	0,P.NICP(L)	;MAXIMUM # OF PAGES
	MOVEM	0,D.MAXA(T3)	;SAVE AS MAX PAGE IN CORE
	MOVEM	0,D.MAXP(T3)	;SAVE AS MAX PAGE
	MOVEM	0,D.NXTP(T3)	;AND NEXT TO GO
	MOVEM	0,TEMP
	PUSHJ	P,ALCOR		;GRAB SOME CORE
	MOVE	T7,0		;SAVE FOR FILL
	ADD	0,[-1(T4)]	;INDEX & OFFSET IT
	MOVEM	0,D.ICPT(T3)	; & SAVE IT
	SETO	T5,0		;DO
	MOVE	T6,TEMP		;ADDR
	PUSHJ	P,FILL		;FILL THE ARRAY
	PUSHJ	P,ALCOR		;FOR D.ICPA TABLE
	ADD	0,[-1(T4)]	;INDEX & OFFSTE IT
	MOVEM	0,D.ICPA(T3)	;& SAVE POINTER
	MOVN	T1,D.MAXP(T3)	;BUILD AOBJN POINTER
	HRLI	T1,(T1)		; ..
	HRR	T1,0		;
	MOVE	0,D.NWOR(T3)	;LENGTH OF PAGE
	$SKPPF <	ADDI	0,2		;EXTRA 2 WORDS IF DEBUG
	>
	MOVEM	0,TEMP		;SAVE
GICP:	PUSHJ	P,ALCOR		;GET AN IN-CORE PAGE
	$SKPPF <	ADDI	0,2		;STEP OVER READS AND WRITES COUNTER
	>
	MOVEM	0,1(T1)		;BUILD D.ICPA
	AOBJN	T1,GICP		;FOR AS LONG AS NECESSARY
	MOVE	T6,TNOP		;GET NO OF PAGES IN TOTLA
	MOVEM	T6,TEMP
	MOVE	T5,[PUSHJ P,WFAULT]
	PUSHJ	P,SVTABS	;SET UP TABLE
	ADD	0,[-1(T1)]	;PATCH IN INDEX AND OFFSET FROM 1
	MOVEM	0,D.WTAB(T3)	;AND SAVE IN DATA BASE
	HLRZ	T6,D.RAND(T3)	;GET SCB
	HRRZ	T6,LKENT(T6)	;GET LOOKUP BLOCK
	MOVE	T6,5(T6)	;LENGTH OF FILE IN WORDS
	MOVE	T7,D.NWOR(T3)	;NO OF WORDS/PAGE
	ADDI	T7,177		;ROUND UP TO NO OF BLOCKS
	TRZ	T7,177		;AND NOW NO OF WORDS/PAGE ROUNDED TO NEAREST BLOCK
	ADDI	T6,-1(T7)	;ROUND UP NO OF WORDS WRITTEN
	IDIVI	T6,(T7)		;AND FIND NO OF PGES WRITTEN
	PUSHJ	P,ALCOR		;GET THE CORE
	HRRZ	T7,0		;ADDRESS OF CORE
	ADD	0,[-1(T1)]	;PATCH IN INDEX FIELD & OFFSET
	MOVEM	0,D.RTAB(T3)	;SET POINTER INTO DATA BASE
	MOVE	T5,[PUSHJ P,RFAULT] ; INSTRUCTION TO BE EXECUTED ON ALLOCATED PAGE
	MOVEM	T6,TEMP	;SAVE COUNT
	PUSHJ	P,FILL		;FILL IT
	MOVE	T6,TNOP		;TOTAL # OF PAGES
	SUB	T6,TEMP		;# UNALLOCATED
	MOVSI	T5,(SETZ 0,0)	;INSTRUCTION TO EXECUTE
	PUSHJ	P,FILL		;FILL IT
	$ATRCE <	MOVEI	L,T.ARG3	;ARGUMENT FOR OPEN
	PUSHJ	P,OPEN.##	;OPEN IT
	MOVE	15,(P)		;GET THE OLD LINK
	MOVEI	L,T.ARG1
	PUSHJ	P,WTB.
	MOVEI	L,T.ARG5
	PUSHJ	P,IOLST.
	PUSHJ	P,FIN.
	>
	MOVE	AC,T3		;RETURN POINTER TO DATA BASE
	POPJ	P,		;&RETURN FROM PROGRAM


NOCORE:	POP	P,L		;RESTORE THE LINK
	MOVEI	0,5		;ERROR CODE 5
	MOVEM	0,P.IERR(L)	;STORE IT
	GOODBYE			;& RETURN
SVTABS:	PUSHJ	P,ALCOR		;GET THE CORE
	HRRZ	T7,0		;ADDRESS

;	FALL INTO FILL


;	FILL FILLS AN ARRAY WITH GIVEN VALUE
;
;	CALLING SEQUENCE IS -
;
;	MOVE	T5,VALUE	;WHAT TO FILL ARRAY WITH
;	MOVE	T6,LENGTH	;LENGTH OF ARRA
;	MOVEI	T7,ADDR		;BASE ADDR
;
;	RETURN HERE ALWAYS
;
;	ON RETURN T5 IS UNALTERED
;		  T6 IS DESTROYED
;		  T7 POINTS TO ADDRESS AFTER END OF ARRAY
;
FILL:	JUMPLE	T6,EFILL	;SKIP IT IF <=0
	MOVEM	T5,(T7)		;DEPOSIT FIRST WORD
	MOVEI	T7,1(T7)	;INCRENET T7
	SOJE	T6,EFILL	;FINISHED?
	ADDI	T6,(T7)		;NO-PREPARE FOR BLT
	HRLI	T7,-1(T7)	;T7 NOW CONTAINS BLT AC
	EXCH	T7,T6		;EXCHANGE THEM
	BLT	T6,-1(T7)	;FILL IT UP
EFILL:	POPJ	P,		; & RETURN

; ALCOR SIMULATES ALCOR. BUT IS QUICKER

ALCOR:	MOVE	T4,TEMP		;# OF WORDS WANTED
	AOS	T4		;INCREMENT BY 1 FOR COUNT
	HRLZM	T4,@ADR		;DEPOSIT AT ADR
	MOVE	0,ADR		;GET BASE
	ADDM	T4,ADR	;INCREMENT ON THE ADDRESS
	ADDB	T4,COUNT	;MODIFY THE COUNT
	JUMPG	T4,SCREW	;COMPLAIN
	AOS	0		;INCREMENT THE ADDRESS PAST THE COUNT
	POPJ	P,		;& RETURN
SCREW:	OUTSTR	[ASCIZ/? ALCOR EXPIRED - SEE W.D.HAY ABOUT THIS
/]
	EXIT


	PAGE
	SUBTTL CLOSE ROUTINE

	HELLO	(PAGCLS)	;ENTRY SEQUENCE
	MOVE	T3,ARG1		;GET DATA BASE POINTER
	MOVE	T1,D.MAXA(T3)	;UNLOCK PAGES BY CHANGING
	MOVEM	T1,D.MAXP(T3)	;D.MAXP
	MOVNI	T1,(T1)	;AND SET UP COUNTER
	PUSHJ	P,GETPAG	;FORCE IT
	AOJL	T1,.-1		;UNTIL FINISHED
	POPJ	P,		;AND RETURN

	PAGE
	SUBTTL LOCK AND UNLOCK ROUTINES

	HELLO	(LOCKP)
	PUSHJ	P,LOCKSU	;SETUP T1-T3
LOCK10:	MOVE	T4,D.MAXP(T3)	;GET MAX PAGE NO
	$PTRCE <
	MOVEM	T1,NPAG
	PUSH	P,L
	MOVEI	L,F1001
	PUSHJ	P,OUT.
	MOVEI	L,F2001
	PUSHJ	P,IOLST.
	POP	P,L
>
	CAIG	T4,2		;MUST HAVE AT LEAST TWO FREE PAGES
	JRST	LOCKEX		;DONT-SO DONT LOCK IT
	PUSHJ	P,FILP		;FIND IN-CORE PAGE
	PUSHJ	P,LOKEXC	;EXCHANGE PAGES (RETURN 1)
	SOS	D.MAXP(T3)	;LOCK IT	(RETURN 2)
LOCKEX:	GOODBYE			;ALREADY LOCKED (RETURN 3)

	HELLO	(ULOCKP)
	PUSHJ	P,LOCKSU	;SETUP T1-T3
ULOC10:	$PTRCE <
	MOVEM	T1,NPAG
	MOVEI	L,F1002
	PUSHJ	P,OUT.
	MOVEI	L,F2001
	PUSHJ	P,IOLST.
	POP	P,L
	>
	PUSHJ	P,FILP		;FIND IN-CORE PAGE
	POPJ	P,		;RETURN 1-WAS UNLOCKED
	POPJ	P,		;    DO
	AOS	D.MAXP(T3)	;UNLOCK THE PAGE
	CAME	T4,D.MAXP(T3)	;IS IT NOW =?
	PUSHJ	P,LOKEXC	;NO-SWOP PAGE REFERENCES
	POPJ	P,		;& RETURN

;	LOCKSU SETS UP AC'S T1-T3 AND FORCES PAGE INTO CORE IF NOT
;	ALREADY THERE
;
LOCKSU:	HRRZ	T3,@S.IDBA(L)	;GET DATA BASE POINTER
	HRRZ	T1,@S.IADR(L)	;GET PAGE NO
	SETZ	T2,		;ZERO OFFSET
	XCT	@D.RTAB(T3)	;DO A READ TO FORCE IN PAGE
	POPJ	P,		;RETURN

FILP:	MOVE	T4,D.MAXA(T3)	;GET MAX PAGE NO
FILP10:	CAMN	T1,@D.ICPT(T3)	;IS IT THIS ONE ?
	JRST	FILP20		;YES
	SOJG	T4,FILP10	;NO-TRY TO GET NEXT ONE
	OUTSTR	[ASCIZ/? PAGE TABLE FOULED UP
/]
	EXIT

FILP20:	CAMGE	T4,D.MAXP(T3)	;>=MAX IN CORE SWAPPING PAGE?
	POPJ	P,		;NO-RETURN 0
	CAME	T4,D.MAXP(T3)	;>MAX IN CORE SWAPPING PAGE?
	AOS	(P)		;RETURN 1
	AOS	(P)		;RETURN 1
	POPJ	P,		;RETURN

;	LOKEXC EXCHANGES REFERENCE TO PAGE POINTED TO BY
;	T4 WITH THAT POINTED TO BY D.MAXP

LOKEXC:	MOVE	T5,@D.ICPA(T3)	;GET ADDREESS POINTED TO
	MOVE	T6,@D.ICPT(T3)	;GET CORRESPONDANCE
	EXCH	T4,D.MAXP(T3)	;SAVE T4, PICK UP D.MAXP
	EXCH	T5,@D.ICPA(T3)
	EXCH	T6,@D.ICPT(T3)
	EXCH	T4,D.MAXP(T3)	;RESTORE T4 AND D.MAXP
	MOVEM	T5,@D.ICPA(T3)
	MOVEM	T6,@D.ICPT(T3)
	POPJ	P,

	HELLO (LOCKA)
	PUSHJ	P,IOPAG		;GET THE AC'S SET UP
	XCT	@D.RTAB(T3)	;FORCE PAGE INTO CORE
	JRST	LOCK10	;AND DO COMMON LOCK STUFF

	HELLO	(ULOCKA)
	PUSHJ	P,IOPAG		;SET UP AC'S
	XCT	@D.RTAB(T3)	;FORCE IN PAGE
	JRST	ULOC10		; & DO COMMON STUFF
	PAGE
	SUBTTL RANRED AND RANWRT PUT HERE

	T11=11
	T12=12
	T13=13

	T10=10
RANRED:
	MOVEI	T10,-1(T1)	;PAGE # -1
	HRRZ	T11,D.RAND(T3)	;NO OF BLOCKS/PAGE
	IMUL	T10,T11		;FIRST BLOCK OF PAGE-1
	AOS	T10		;FIRST BLOCK
	HLRZ	T11,D.RAND(T3)	;GET SCB
	IOR	T10,USETI(T11)	;FORM USETI
	XCT	T10		;DO IT
	MOVN	T10,D.NWOR(T3)	;LENGTH OF PAGE
	HRL	T10,TEMP	;ADDRESS
	MOVSM	T10,CLST	;IOWD+1
	SOS	CLST
	SETZM	CLST+1		;MAKE SURE IT TERMINATES
	MOVE	T10,IBUFOP(T11)	;MAKE AN IN UUO
	HRRI	T10,CLST
	XCT	T10		;EXECUTE IT
	POPJ	P,		;OK

	OUTSTR	[ASCIZ/?PAGINF ERROR ON PAGING READ
/]
	EXIT


RANWRT:
	MOVEI	T10,-1(T1)	;PAGE # -1
	HRRZ	T11,D.RAND(T3)	;NO OF BLOCKS/PAGE
	IMUL	T10,T11		;FIRST BLOCK OF PAGE-1
	AOS	T10		;FIRST BLOCK
	HLRZ	T11,D.RAND(T3)	;GET SCB
	IOR	T10,USETO(T11)	;FORM USETI
	XCT	T10		;DO IT
	MOVN	T10,D.NWOR(T3)	;LENGTH OF PAGE
	HRL	T10,TEMP	;ADDRESS
	MOVSM	T10,CLST	;IOWD+1
	SOS	CLST
	SETZM	CLST+1		;MAKE SURE IT TERMINATES
	MOVE	T10,OBUFOP(T11)	;MAKE AN IN UUO
	HRRI	T10,CLST
	XCT	T10		;EXECUTE IT
	POPJ	P,		;OK


	OUTSTR	[ASCIZ/PAFOUF ERROR IN PAGING WRITE
/]
	EXIT
CLST:	BLOCK	2	;IOWD

	PAGE
	SUBTTL	DEBUGGERY
	IFN TRACEP,<

NPAG:	0
OPAG:	0
READS:	0
WRITES:	0
	XWD	-5,0
F1000:	24
	0
	0
	XWD	340,[ASCIZ/(' C',4I6)/]
	2

	XWD	-5,0
F2000:	XWD	1100,NPAG
	XWD	1100,OPAG
	XWD	1100,READS
	XWD	1100,WRITES
	XWD	4000,0

	XWD	-5,0
F1001:	24
	0
	0
	XWD	340,[ASCII/(' L',I6)/]
	2

	XWD	-2,0
F2001:	XWD	1100,NPAG
	XWD	4000,0

	XWD	-5,0
F1002:	24
	0
	0
	XWD	340,[ASCII/(' U',I6)/]
	2
>
	PAGE
	SUBTTL TRACE STUFF
	IFN TRACEA,<

	XWD	-3,0
T.ARG1:	XWD	0,20
	XWD	0,0
	XWD	0,0

	XWD	-2,0
T.ARG2:	XWD	1100,T.ADDR
	XWD	4000,0

	XWD	-6,0
T.ARG3:	XWD	0,20
	0
	0
	XWD	3740,[ASCII/MTA0/]
	XWD	2740,[ASCIZ/SEQOUT/]
	XWD	12740,[ASCIZ/IMAGE/]
	XWD	4100,[EXP 6]

	XWD	-3,0
T.ARG5:	XWD	1100,@P.LBND(15)
	XWD	1100,@P.UBND(15)
	XWD	4000,0

T.ADDR:	0
>
	END
