Google
 

Trailing-Edge - PDP-10 Archives - AP-D543V_SB - kaser.mac
There are 7 other files named kaser.mac in the archive. Click here to see a list.
TITLE	KASER - PDP-6 AND KA10 PROCESSOR DEPENDENT CODE - V2072
SUBTTL	APRINT TH/TH/CHW/RCC/PFC/JE/DAL  13 JUN 78
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
XP VKASER,2072
		; PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP

	ENTRY	KASER		;LOAD KASER IF LIBRARY SEARCH
KASER:

;THIS SERVICE ROUTINE RUNS ON A HIGH PRIORITY CHANNEL
;AND REQUESTS INTERRUPTS ON LOWER CLK CHANNEL
;FOR SCHEDULING JOBS AND ERROR HANDLING THAT THE USER
;IS NOT ENABLED TO HANDLE HIMSELF


SUBTTL	CLOCK - LOW PRIORITY CLOCK SERVICE(CLK)

;THIS ROUTINE RUNS ON THE LOWEST PRIORITY PI CHANNEL AND AT UUO LEVEL
;TO CAUSE AN INTERRUPT ON CLK CHANNEL:
;	SETOM CLKFLG	;FLAG THAT INTERRUPT HAS BEEN REQUESTED
;	CONO PI,CLKREQ	;REQUEST PI INTERUPT ON LOWEST PI CHANNEL
;THE FOLLOWING OTHER FLAGS MUST ALSO BE SET
;APRERR-APR DETECTED ERROR IN CURRENT JOB
;SCHEDF-RESCHEDULING MUST TAKE PLACE(EVEN THOUGH PC IN EXEC MODE)
;TIMEF-APR CLOCK HAS TICKED ON HIGH PRIORITY CHANNEL
;SEE APRSER AND RUNCSS TO SEE HOW THIS ROUTINE IS CALLED

;CLK SERVICE PERFORMS THE FOLLOWING ON A REGULAR BASIS:
;PROCESSES CLOCK QUEUE REQUESTS
;CALLS CONSOLE MONITOR COMMAND DECODER
;CALLS CORE SHUFFLER
;THEN CALLS SCHEDULER
;IF THE CURRENT JOB IS IN EXEC MODE THE ABOVE 4 TASKS ARE
;DELAYED UNTIL THE CURRENT JOB ENTERS A STOPPABLE STATE: I.E., UNTIL
;	1. JOB STARTS TO WAIT FOR A BUSY SHARABLE DEVICE
;	2. JOB STARTS TO WAIT FOR IO TO COMPLETE
;	3. CONTROL ABOUT TO RETURN TO USER MODE
;THEN CLK SERVICE IS ENTERED AT THE UUO LEVEL

REPEAT 0,<
;*** OLD ACCUMULATOR ASSIGNMENTS, CHANGED JUNE 1, 1971
STOR=U
T=T1
T1=T2
JA=R
>

;THE CLOCK REQUEST QUEUE PROVIDES THE REST OF THE MONITOR
;WITH THE ABILITY TO BE TRAPPED TO AFTER A NUMBER OF CLOCK TICKS
;HAVE OCCURRED

;TO MAKE A REQUEST:
;	CONO PI,PIOFF
;	IDPB AC,CLOCK	;STORE CLOCK REQUEST IN QUEUE
;	CONO PI,PION	;TURN PI BACK ON
;C(AC)=XWD ADDRESS,NO. OF CLOCK TICKS+DATA*10000
;WHERE DATA IS 6 BITS OF INFO NEEDED WHEN TIME RUNS OUT
;CLK SERVICE WILL PUSHJ P,ADR
;WHEN TIME RUNS OUT WITH DATA RIGHT JUSTIFIED IN AC T1
;ALL ACS ARE FREE TO USE WHEN CALL IS MADE
;HERE AT CLK INTERRUPT LEVEL

INTERNAL CK0INT,CIP8B
INTERNAL FTTIME
;************************************************
;THIS CODE IS DUPLICATED IN SLVSER FOR CPU1

CK0INT:	SKIPN	.C0CKF##	;CLK INTERRUPT REQUEST?
	JRST	CK0INT		;NO, CHECK OTHER DEVICES
	MOVEM	17,.C0S17##	;SAVE AC 17
	MOVE	17,CK0CHL	;IS CURRENT JOB IN USER MODE?
	TLNN	17,USRMOD
	SKIPE	.C0SCF##	;NO, IS THIS A FORSCED RESCHEDULING INTERRUPT?
	JRST	SAVPC		;YES, IT IS OK TO RESCHEDULE NOW
	MOVE	17,.C0S17##	;NO, LEAVE TIMEF SET AND DISMISS INT.
	JEN	@CK0CHL##

;HERE ON CLK (USUALLY PI7) INTERRUPT FOR CPU0 FOR KA10 OR KI10)
;NO ACS SAVED OR SETUP YET
SAVPC:	MOVEM	17,.C0PC##	;SAVE PC IN PROTECTED PART OF SYSTEM DATA
				; STORAGE FOR CURRENT JOB
;HERE ON APR ERROR WITH ALL AC RESTORED
	SKIPN	17,.C0ADR##	;CURRENT JOB DATA AREA, IS THERE ONE?
	MOVE	17,.C0NJD##	;NO, MUST BE NULL JOB OR CORE 0
				; RUNS AT UUO LEVEL,REQUESTS CLK INT. TO STOP
	MOVEM	16,JOBD16##(17)	;SAVE AC 16 IN DUMP AC PART OF JOB DATA AREA
	MOVEI	16,JOBDAC##(17)	;SOURCE=0,DESTINATION=DUMP AC 0
	BLT	16,JOBD15##(17)	;SAVE ACS 0-15 JUST BELOW AC 16
	MOVE	T1,.C0S17	;NOW SAVE 17 IN JOB DATA AREA
	MOVEM	T1,JOBD17##(17)	;ALONG WITH OTHER ACS
CK0SPD::MOVE	P,.C0NPD##	;SET UP PUSH DOWN LIST IN NULL JOB DATA
				; AREA IN LOWER CORE
	JRST	CHKAPE##	;CHECK FOR APR ERRORS, DO COMMAND DECODING
				; AND RESCHEDULE

;HERE AFTER CALLING SWAPPER, SCHEDULER, COMMAND DECODER, ETC.
; RESTORE AC'S OF (NEW) CURRENT USER
CIP8B:	MOVSI	17,JOBDAC##(R)	;RESTORE DUMP ACS
	BLT	17,17
	SKIPE	.C0AEF##	;DID AN ERROR OCCUR WHILE CLK PI IN PROGRESS
				; (ON CLK PI OR HIGHER) OR ON CPU1
	JRST	CK0SPD		;YES, GO PROCESS ERROR NOW THAT ON CPU0
	JEN	@.C0PC##	;DISMISS CHANNEL(IF INTERRUPT IN PROGRESS)
;ROUTINE TO SET HARDWARE AND SOFTWARE RELOCATION INFORMATION FOR CURRENT USER
;CALLED FROM:
;	CLOCK ROUTINE WHEN NEW USER IS DIRRERENT FROM OLD USER
;	CORE ROUTINE WHEN CORE REASSIGNED FOR CURRENT USER
;	CORE UUO
;	REMAP UUO
;	CALL RESET UUO
;	CALL SETUWP UUO
;	CALL WHENEVER OLD HIGH SEG IS REMOVED FROM ADR.  SPACE FOR CURRENT JOB

;CALL:	STORE RELOCATION AND PROTECTION FOR LOW SEG IN JOBADR(JOB NUMBER)
;	STORE LENGTH-1 AND ABS ORIGIN FOR HIGH SEG IN JBTADR(HIGH SEG NO)
;	(MOVE J,JOB NUMBER - IF CALLING SETRL1)
;	PUSHJ P,SETREL OR SETRL1
;	ALWAYS RETURN, C(J)=JOB NUMBER, C(R)=XWD PROT,RELOC, FOR LOW SEG

	INTERN	SETREL,SETRL1
	EXTERN	JBTADR,JBTDAT,JOBREL,JOBENB
	EXTERN	JBTSGN,JOBHRL,JOBHCU

SETREL:	PUSH	P,P4		;SAVE P4
	MOVEI	P4,.C0CDB	;SET UP CDB POINTER
	SKIPA	J,.C0JOB##	;CURRENT JOB NUMBER
SETRL1:	PUSH	P,P4		;SAVE P4
	MOVE	R,JBTADR(J)	;XWD PROTECTION,RELOCATION FOR LOW SEG
	MOVEM	R,.CPADR##(P4)	;SAVE TO MAKE UUO HANDLER FASTER
	HLRZM	R,.CPREL##(P4)	;SAVE PROTECTION FOR ADDRESS CHECKING
				; (HIGHEST LEGAL REL ADDRES FOR CURRENT USER IN LOW SEG)
	JUMPN	R,SETRLZ	;IF 0 (NULL JOB OR JOB DOING CORE 0 OR KJOB)
				; DO NOT STORE IN JOB DATA AREA (SINCE IT WILL BE
				; IN EXEC LOWER CORE.  ALSO DO NOT STORE
				; IN LOC 33, SO CAN SEE LAST REAL USER TO RUN

IFN FTTRPSET,<
	SKIPE	.CPSTS##(P4)	;IS TIME SHARING STOPPED BY TRPSET UUO?
	JRST	SETHD1		;YES, DO NOT CHANGE RELOC FROM REAL TIME JOB
				; SO CAN TRAP DIRECTLY TO HIM ON AN INTERRUPT
>	;END FTTRPSET COND
	MOVE	R,[XWD 777,776400] ;SET HIGH SEG TO POINT AT MONITOR
				;WITH WRITE PROTECTION TURNED ON
				;NO, SET RELOCATION HARDWARE TO NON-EXIST
				; MEMORY, SO IF NULL JOB GETS CLOBBERRED, IT
				; WILL GET A NXM INSTEAD OF HURTING MONITOR
				; OR A USER.
	JRST	SETHRD		;DO DATAO
SETRLZ:
	HLRZM	R,JOBREL(R)	;SET PROTECTION IN USER JOB DATA AREA
				; FOR HIM TO LOOK AT
IFN FT2REL,<
;HERE TO ADJUST AC R SO THAT IT HAS PROPER RELOCATION AND PROTECTION
;INFORMATION FOR CURRENT JOB, SO THAT A DATAO APR, R CAN BE DONE.
SETHGH:	PUSH	P,P1		;SAVE P1
	MOVE	P1,JBTSGN##(J)	;HIGH SEG NUMBER
	PUSHJ	P,HSVAD##	;T1=STARTING ADDR. OF HIGH SEG, T2=
				; HIGHEST LEGAL ADDR IN HI-SEG
	SKIPGE	JOBHCU(R)	;DO NOT STORE IN JOBHRL IF SAVE OR GET IN PROGRESS
	JRST	NOHGH1		; BECAUSE IT USES THESE LOCATIONS FOR ZERO COMPRESSION
	HRRM	T1,JOBHRL(R)	;STORE IN USER AREA SO HE CAN LOOK AT IT.
				;LH UNALTERED(HIGHESTREL  LOC LOADED+1 BY LOADER)
				;0 MEANS NO HIGH SEG
NOHGH1:	LSH	T1,-12		;RIGHT JUSTIFY 8 BIT PROTECTION FOR HIG SEG
	DPB	T1,[POINT 8,R,16]	;STORE IN POSITION FOR DOING DATAO APR,R
				;IF NO HIGH SEG, 0 WILL CAUSE FAILURE IF REF
	SKIPGE	P1		;IS THIS ASPY SEG?
	TDZA	T1,T1		;YES, ABS. ADR OF BEGINNING IS 0
				; (P1 HAS HIGHEST PAT ADR USER WANTS
	HRRZ	T1,JBTADR(P1)	;ABSOLUTE ADR. OF BEG. OF HIGH SEG
	SUBI	T1,(T2)		;SUBTRACT 400000 OR LENGTH OF LOW SEG(IF GREATER)
	LSH	T1,-11		;SHIFT RELOC. FOR HIGH SEG TO POSITION FOR DATAO
	ANDI	T1,776		;MASK OUT ALL BUT 8 BITS
	IOR	R,T1		;INSERT RELOC AND PROT FOR HIGH SEG IN R
	TLO	R,UWP		;ASSUME USER-MODE WRITE PROTECT IS ON
	TLNE	P1,UWPOFF	;HAS USER DONE A SETUWP UUO AND TURNED OFF UWP?
				; (AND HAS NOT MEDDLED WITH PROGRAM)
	TLZ	R,UWP		;YES, SET UWP OFF FOR DATAO
	POP	P,P1
>
IFE FT2REL,<
	TLZ	R,1777		;CLEAR OUT PROTECTION FOR HIGH SEG 
				; JUST IN CASE THIS IS A 2 REG. MACHINE(EVEN THOGH
				; SOFTWARE CANNOT HANDLE 2 SEGS)
>
SETHRD:	MOVEM	R,.CPDTO##(P4)	;STORE IN LOWER CORE SO IT CAN BE FOUND OUT
				; USING SWITCHES WHAT IS IN SECOND REGISTER
				; OPTION DOES NOT COME WITH PANEL LIGHTS
				; SO NOT STORE 0 FOR NULL JOB SO CAN SEE
				; LAST JOB TO RUN IN LOC 33
	DATAO	APR,R		;SET APR HARDWARE FOR RELOCATION AND PROTECTION
				; FOR LOW(AND HIGH SEGS)
SETHD1:	SKIPN	R,.CPADR##(P4)	;RESTORE R TO XWD PROT,RELOC FOR JUST LOW SEG
				; (IS THERE ONE)?
	TDZA	T1,T1		;NO, MUST BE NULL JOB OR CORE0 OR KJOB
				; SET FOR NO SPECIAL INTERRUPTS TO USER
	MOVE	T1,JOBENB(R)	;USER APR CONSO FLAGS (THE ONES HE WANTS TO HANDLE
	JRST	SETAP1		;DON'T SET UP P4 AGAIN
;ROUTINE TO ENABLE/DISABLE APR FOR TRAPPING TO USER AND EXEC
;CALL:	MOVEI T1, APR CONSO FLAGS FOR USER TRAPPING
;	PUSHJ P,SETAPR
;	RETURN WITH APR RESET AND INTERRUPT LOCATION CONSO'S SET

	INTERN	SETAPR,SETAP1

SETAPR:	PUSH	P,P4		;SAVE P4
	MOVEI	P4,.C0CDB##	;SET UP CDB INDEX FOR CPU0
SETAP1:	AND	T1,.CPFO1##(P4)
				;MASK OUT ALL BUT PD OVF, ILL MEM, NXM,
				; CLOCK, FOV(ONLY PDP-10), AND AROVF CONSO FLAGS
				; AND USER ENABLED MEM PARITY (UE.PEF)
				; FOV=PC CHANGE ON PDP-6 WHICH IS NEVER ALLOWED
				; UNDER TIME SHARING BECAUSE IT TRAPS MONITOR TOO
	HRLS	T1		;PRESERVE USER BITS IN LH
	TRO	T1,AP.POV+AP.NXM+AP.ILM+XP.CLK+AP.ABK
				;MAKE SURE MONITOR ALWAYS LOOKING FOR
				; PD OVF, ILM, NXM, ADDRESS BREAK CLOCK FLAGS
	MOVE	T2,T1		;DUPLICATE BITS IN T2 FOR CONO TO APR.
	XOR	T2,.CPFO2##(P4)	;COMPLEMENT FOV(PDP-10 ONLY) AND AROV FLAGS
	ADDI	T2, 330		;SET DISABLE OR ENABLE FOR EACH
	ANDI	T2,660		;MASK OUT ALL BUT DISABLE/ENABLE
				; BITS FOR FOV(PDP-10 ONLY) AND AROVF
	ADDI	T2,@.CPAPI##(P4)	;ADD IN APR PI FOR THIS CPU
				; (KI-10 HAS TWO PIS)
	CONO	PI,PIOFF##	;DISABLE PI'S SO NO INTS. MAY OCCUR WHILE
				;CHANGING HARDWARE & SOFTWARE STATE FOR
				;APR TRAPPING
	HLRM	T1,.CPCN1##(P4)	;STORE USER BITS
	HRRM	T1,.CPCON##(P4)	;STORE EXEC BITS
	HRRZM	T2,.CPLUC##(P4)	;STORE APR MASK FOR INTERRUPT LEVEL USE
	TRO	T2,AP.CAO+AP.CFO  ;CLEAR POSSIBLE TRAP FLAGS
	CONO	APR,(T2)	;ENABLE OR DISABLE APR FOR
				; FOV(PDP-10 ONLY) AND AR OVF SEPARATELY
	CONO	PI,PION##	;ENABLE PI'S AGAIN
	POP	P,P4		;RESTORE P4
	POPJ	P,
;ROUTINE TO CAUSE CLK ROUTINE TO RESCHEDULE
;CALLED AT ANY LEVEL
;CALL:	PUSHJ P,STOP2	
;	RETURN IMMEDIATELY EXCEPT IF AT UUO LEVEL
;	IF AT UUO LEVEL, RETURN WHEN JOB IS RUNABLE AGAIN

INTERNAL STOP2

STOP2:	CONO	PI,PIOFF##	;PREVENT CLOCK INTERRUPT DURING STOP2 CODE
	SETOM	.C0CKF##	;SET FLAG TO INDICATE CLK INTERRUPT
				; EVEN THOUGH CLK INTERRUPT IS NOT A TIME INTERRUPT
	CONO	PI,PICLK##	;TURN PI BACK ON AND REQUEST INTERRUPT TO
				; CLK PI CHANNEL(LOWEST PRIORITY CHANNEL)
	POPJ	P,		;INTERRUPT IMMEDIATELY IF AT UUO LEVEL

SUBTTL	CORE1 - CORE ALLOCATION MODULE

;SUBROUTINE TO SWEEP MEMORY TO FIND ADDRESS AND CONTENTS OF BAD WORDS
;IT CALLS CPU INDEPENDENT SUB.(PARERR##) TO RECORD DATA ON EACH BAD WORD
;CALL:	MOVE	P4,ADR OF CPU DATA BLOCK
;	PUSHJ	P,@.CPMPS##(P4)
;	ALWAYS RETURN WHEN SWEEP OVER (EVEN IF SERIOUS ERROR)
;SWEEP CORE IN ASCENDING ADDRESSES EVEN THOUGH SLOWER, SO DATA STORED ASCENDING
; FOR ERROR REPORTING WITH DAEMON

IFN FTMEMPAR,<			;MEMORY PARITY ANALYSIS

	INTERN	CPAMPS

CPAMPS:	PUSHJ	P,SAVE3##	;SAVE P1,P2 FOR BAD ADR, CONTENTS
	MOVEI	P1,0		;SCAN ALL OF CORE (INCLUDING ACS IN CASE FAST ACS OFF)
	MOVE	P3,[POINT 1,NXMTAB##]	;BYTE PTR TO NXMTAB
MPSLOP:	CAML	P1,MEMSIZ##	;SCANNED ALL OF MEMORY?
	POPJ	P,		;YES, RETURN
	TRNE	P1,PG.BDY##	;FIRST WORD OF THIS PAGE?
	JRST	MPSLP1		;NO
	ILDB	T1,P3		;GET BIT INDICATING WHETHER NXM
	JUMPE	T1,MPSLP1	;JUMP IF NOT NXM
	ADDI	P1,PAGSIZ##	;NON-EXISTANT, SKIP THIS PAGE
	JRST	MPSLOP		;CHECK NEXT PAGE
MPSLP1:
IFN FTMEMNXM,<
	TRNN	S,UE.PEF	;NXM RATHER THAN PARITY ERROR?
	JRST	[CONSO APR,AP.NXM
		JRST MPI
		CONO APR,AP.CNM
		SOJA P1,MPSBD1]
>
	CONSZ	PI,PI.PAR	;MEMORY PARITY FLAG ON (ONLY IF SWEEP AT APR PI)
	JRST	[CONO PI,XI.CPE	;CLEAR PARITY FLAG
	SOJA	P1,MPSBAD]	;DECREMENT SO ADR OF BAD WORD
;SPECIAL INSTRUCTION ADDRESS - REFERENCE MEMORY TO SEE IF BAD
	XP	CPAMPI,MPI+1	;PC VALUE WHEN APR GETS PARITY INT.
				;USED BY APR PI ROUTINE TO MAKE INSTR. SKIP
MPI:	SKIP	P2,(P1)		;DOES THIS LOC HAVE BAD PARITY (PICKUP IN P2)?
	JFCL			;APR INT ADDS 2 TO PC INCASE THIS IS KI
	AOJA	P1,MPSLOP	;NO, KEEP LOOKING

;HERE ON BAD PARITY FOUND - APR OR PI 7 (APR INTERRUPT ADDED 2 TO PC)
MPSBAD:	MOVEM	P2,(P1)		;FIX UP BAD PARITY, SO THAT NUMBER OF BAD
				; PARITY WORDS IN MEMORY IS MINIMIZED.  THIS
				; DECREASES CHANCES OF NOT DETECTING
				; READ-PAUSE-WRITE SITUATION (0 ERRORS)
				; BECAUSE ANOTHER BAD WORD IS PRESENT
MPSBD1:	PUSHJ	P,CPAASN	;YES, CONVERT TO SEG NUMBER, (J), REL ADR (T1)
	  SETOM	T1		;FLAG ABS. ADR NEITHER IN MONITOR NOR A SEGMENT.
	PUSHJ	P,PARRBD##	;RECORD BAD DATA (T1=REL ADR, P1=BAD ADR,P2=
				; BAD CONTENTS)
	AOJA	P1,MPSLOP	;STEP TO NEXT ABSOLUTE ADDRESS
;SUBROUTINE - ABSOLUTE (ADDRESS TO) SEGMENT NUMBER
;CALL:	MOVE	P1,ABS.ADR(18 BIT FOR KA-10, 22 BIT FOR KI10)
;	PUSHJ	P,@CP.ASN(P4)
;	  ERROR RETURN IF NOT IN MONITOR OR A HIGH OR LOW SEGMENT,
;	OK RETURN J=0 IF IN MONITOR, OR HIGH OR LOW SEG, T1=REL. ADR
;CAN BE CALLED AT APR PI OR CLK PI(7)
;NOTE:  REL ADR. IS NOT VIRTUAL ADR ON HIGH SEGS
; SINCE THAT IS JOB DEPENDENT IF LOW SEG GR 400000

	INTERN	CPAASN

CPAASN:	MOVEI	J,0		;ASSUME IN MONITOR (JOB 0 NOT LEGAL JOB#)
	MOVE	T1,P1		;SET REL. ADR. FROM ABS ADDRESS IN MONITOR
	CAMGE	P1,SYSSIZ##	;IS ABS ADR IN MONITOR?
	JRST	CPOPJ1##	;YES, GIVE OK RETURN WITH J=0
	MOVEI	J,JBTMAX##	;NO, MAX NO. OF JOBS AND HIGH SEGS
;LOOP - SCAN ALL HIGH AND LOW SEGS
ASNLOP:	SKIPE	T1,JBTADR##(J)	;IS THIS JOB OR HIGH SEG IN CORE?
	CAIGE	P1,(T1)		;YES, IS ABS. ADR ABOVE SEG ORIGIN?
ASNSOJ:	SOJG	J,ASNLOP	;NO, LOOK FOR ANOTHER SEG
	JUMPLE	J,CPOPJ##	;YES, FINISHED SCAN
	HLRZ	T2,T1		;PROTECTION - HIGHEST LEGAL REL ADR.
	HRRZ	T1,T1		;FORM JUST ORIGIN
	SUBM	P1,T1		;REL. ADR=ABS ADR - ORIGIN
	CAMLE	T1,T2		;REL ADR LESS THAN OR EQ TO HIGHEST REL ADR?
	JRST	ASNSOJ		;NO, NOT RIGHT SEG, GO LOOK FOR ANOTHER
	JRST	CPOPJ1##	;YES, GIVE OK RETURN, J SET TO SEG#, T1=REL. ADR.
>				;END FTMEMPAR
IFN FTMEMNXM,<
;SUBROUTINE TO FIX CORE ALLOCATION TABLE AND VARIABLES AFTER NON-EXISTANT
; MEMORY IS ENCOUNTERED
;CALLING SEQUENCE:
;	MAKE NXMTAB REFLECT CURRENT STATE OF MEMORY, GIVE BACK CORE
;	BELONGING TO SEGMENTS WHICH OVERLAP NXM, AND
;	PUSHJ	P,CPANXF	;FIX UP RELEVANT TABLES AND VARIABLES
;RETURNS CPOPJ IF NEW VALUE OF CORMAX .LT. OLD VALUE OF CORMAX (SOME
; JOB MAY BE TOO BIG TO SWAP IN), CPOPJ1 IF ALL IS OK

CPANXF::PUSHJ	P,SAVE3##	;SAVE WORKING ACS
	MOVE	T1,[POINT 2,CORTAB##]
	MOVE	T2,[POINT 1,NXMTAB##]
CPANX1:	ILDB	T3,T1		;BYTE FROM CORTAB
	ILDB	T4,T2		;BYTE FROM NXMTAB
	JUMPE	T4,CPANX2	;JUMP IF THIS K OF MEMORY EXISTS
	CAIN	T3,CTNXMI##	;ALREADY MARKED AS NON-EXISTANT?
	JRST	CPANX2		;YES, NOTHING TO DO
	SKIPE	T3		;IS THIS K OF MEMORY FREE?
	STOPCD	.,STOP,NPN,	;++NON-EXISTANT K NOT FREE
	MOVEI	T3,CTNXMI##	;MARK IT AS NON-EXISTANT
	DPB	T3,T1		; ..
	SOS	CORTAL##	;DECREMENT COUNT OF FREE+DORMANT+IDLE K
CPANX2:	CAME	T1,CORLST##	;LOOKED AT ALL OF MEMORY?
	JRST	CPANX1		;NO, CHECK THE NEXT K
;HERE TO UPDATE MEMSIZ, CORLST
	MOVEI	P3,1		;SEARCH FOR EXISTANT MEMORY
	MOVEI	T1,-1		;FIND THE LARGEST CHUNK
	PUSHJ	P,HOLSRT	; ..
	  MOVEI	T1,-1(P2)	;ALWAYS NON-SKIP RETURN
	PUSHJ	P,HOLSRT	;NOW FIND OUT WHERE IT IS
	  JFCL			; ..
IFN FTLOCK,<
	MOVEM	T3,HOLEF1##	;STORE THE ADDRESS OF THE LARGEST HOLE
>
	ADDI	T3,1(T4)	;HIGHEST ADDRESS IN THE LARGEST HOLE
IFN FTLOCK,<
	MOVEM	T3,HOLTOP##	;REMEMBER THAT
>
	PUSH	P,P1		;SAVE THE BYTE POINTER TO THE TOP OF THE HOLE
CPANX3:	CAMN	P1,CORLST##	;REACHED THE TOP OF CORE WHICH WAS THERE?
	JRST	CPANX4		;YES
	ILDB	T1,P1		;NEXT BYTE FROM CORTAB
	CAIL	T1,CTNXMI##	;DOES THIS K EXIST?
	JRST	CPANX3		;NO, LOOK AT THE NEXT 1K BLOCK
	MOVEM	P1,(P)		;YES, SAVE BYTE POINTER TO HIGHEST EXISTANT BLOCK
	ADDI	T3,PAGSIZ##	;UPDATE HIGHEST ADDRESS IN MEMORY
	JRST	CPANX3		;LOOP OVER ALL OF MEMORY
CPANX4:	POP	P,CORLST##	;SET BYTE POINTER TO HIGHEST EXISTANT BYTE
	MOVEM	T3,MEMSIZ##	;NEW HIGHEST ADDRESS IN MEMORY + 1
	CAML	T4,CORMAX##	;TOTAL NUMBER OF PAGES OF EXISTANT MEMORY
				; LESS THAN CORMAX?
	JRST	CORPRM		;NO, ALL JOBS CAN CONTINUE TO RUN
	MOVEM	T4,CORMAX##	;STORE NEW SMALLER CORMAX
	MOVEM	T4,MAXMAX##	;AND MAX FOR CORMAX
	SOS	(P)		;INDICATE THAT SOME JOBS MAY NOT BE ABLE
				; TO RUN (THEY MIGHT BE TOO BIG TO SWAP IN)
	JRST	CORPRM		;GO ADJUST OTHER PARAMETERS AND RETURN
> ;END FTMEMNXM
;ROUTINE TO CHECK JOBS TO SEE IF ANY JOB CAN BE SHUFFLED
;IT IS CALLED EVERY 60TH OF A SECOND BY CLOCK ROUTINE
;PROVIDING CURRENT JOB IS IN USER MODE OR JUST ENTERING
;IO WAIT OR SHARABLE DEVICE WAIT OR RETURNING ON UUO CALLS
;IE CURRENT JOB AND ALL OTHER JOB ARE SHUFFABLE WITH RESPECT
;TO RELOCATION INFO IN MONITOR
;SINCE RESCHEDULING IS NEVER DONE WHEN CURRENT JOB
;IS NOT SHUFFABLE, ALL JOBS ARE SHUFFABLE WHEN
;CHKSHF IS CALLED.
;THE NOSHUFFLE MACRO SHOULD STILL BE USED WHEN EVER
;THE MONITOR MOVES RELOCATION OUT OF ACS P OR R
;IN CASE IT SHOULD PROVE DESIRABLE IN THE FUTURE TO SHUFFLE
;MORE FREQUENTLY THAN AT THE ABOVE TIMES
;FINALLY A JOB MUST HAVE ALL DEVICES INACTIVE(SINCE SOME
;OF THEM USE ABSOLUTE ADDRESSES)BEFORE IT CAN BE MOVED
;SO CORE CANNOT BE REASSIGNED WHILE DEVICES ARE ACTIVE
;IF DEVICES ARE ACTIVE, JOB WILL BE STOPPED SO THAT IO WILL
;CEASE SOON SO JOB CAN BE SHUFFLED
;ALL DEVICES LOOK AT SHF BIT IN JBTSTS(ADVBFF OR ADVBFE)
;TO SEE IF MONITOR IS WAITING TO SHUFFLE JOB
;THE NSHF BIT IN JBTSTS WHOULD BE SET FOR JOBS USING DISPLAYS
;SINCE DISSER CONTINUALLY REFERENCES USER AREA EVEN THOUGH
;IOACT IS OFF.
;THIS VERSION OF THE CORE SHUFFLER WORKS AS FOLLOWS:
;EVERY CLOCK TICK FOR WHICH ALL JOBS ARE SHUFFABLE(NOT COUNTING ACTIVE
;IO DEVICES), THE HIGHEST JOB IN CORE WHICH WILL EXACTLY
;FIT IN THE LOWEST HOLE IN CORE IS MOVED DOWN INTO THE HOLE (TRY TO FIND ONE WITHOUT
;ACTIVE IO DEVICES).  IF NONE EXACTLY FIT THE ONE ABOVE THE LOWEST HOLE
;(IF ANY) WILL BE MOVED DOWN INTO HOLE.  THE HOLEF IS SET NON-ZERO
;TO THE ADDRESS OF JOB IMMEDIATELY ABOVE THE LOWEST
;HOLE(0 IF NONE), EVERY TIME CORE IS REASSIGNED.  HOLES IS SET TO THE SIZE OF THE HOLE.
;CANNOT BE CALLED WHILE SWAPPING IN PROGRESS FOR THIS JOB(BECAUSE IT CALLS CORE0)

	INTERN	FTSWAP,FTLOCK
	EXTERN	SHFWAT,HOLEF,JBTADR,JBTSTS,JBTMAX,HOLES
IFN FTLOCK,<
	INTERN	SHFLOP,CORSTG,CORST0,CORST1,CORST2,DIDLE
>

IFN FTSHFL,<			;SHUFFLER PRESENT?

CHKSHF::SKIPE	J,SHFWAT	;HAS CHKSHF STOPPED A JOB AND IS WAITING FOR
				; DEVICES TO BECOME INACTIVE?
	JRST	SHFLOP		;YES, SEE IF IO HAS STOPPED YET
	SKIPN	HOLEF		;NO, DOES CORE HAVE A HOLE IN IT
	POPJ	P,		;NO
	MOVEI	J,JBTMAX	;SEARCH FOR HIGHEST JOB THAT WILL EXACTLY FIT
	MOVSI	P1,-1		;TRY TO PICK ONE THATS NOT IN IO WAIT
	MOVEI	T2,0		;P1 WILL CONTAIN ADDRESS OF JOB, T2 JOB#
IFN FTLOCK,<
	MOVSI	T3,NSHF		;LOCKED JOBS ARE NEVER CANDIDATES
>
CHKSH1:	HRRZ	T1,JBTADR(J)	;T1_ADDRESS OF THIS JOB
	MOVE	P2,HOLEF	;P2_ADDRESS OF THE HOLE
IFN FTLOCK,<
	TDNN	T3,JBTSTS(J)	;IS IT LOCKED?
>
	CAILE	P2,(T1)		;IS JOB BELOW THE HOLE?
	JRST	CHKSH3		;YES, CAN'T POSSIBLY FIT
	JUMPN	T2,CHKSH2	;DON'T CHECK JOB ABOVE THE HOLE IF ONE ALREADY FOUND
	CAIN	P2,(T1)		;DEFAULT IS JOB ABOVE THE HOLE
	MOVE	T2,J		;REMEMBER JOB NUMBER, DON'T KNOW IO STATE
CHKSH2:	HLRZ	P2,JBTADR(J)	;P2_SIZE OF THIS SEGMENT
	CAME	P2,HOLES	;SAME SIZE AS HOLE
	JRST	CHKSH3		;NO, KEEP LOOKING
	MOVE	R,JBTDAT(J)	;ANYACT REQUIRES R
	PUSHJ	P,ANYACT##	;ANY ACTIVE IO DEVICES?
	  HRROS	T1		;YES, REMEMBER THIS JOB IS IN IO WAIT
	CAMG	T1,P1		;HIGHEST SO FAR?
	JRST	CHKSH3		;NO, DOESN'T QUALIFY AS BEST CHOICE
	HRRO	T2,J		;REMEMBER JOB NUMBER AND INDICATE IO STATE KNOWN
	MOVE	P1,T1		;SAVE ADDRESS AND IO STATE
CHKSH3:	SOJG	J,CHKSH1	;LOOK AT ALL SEGMENTS
	MOVEI	J,(T2)		;J_0,,JOB#
	JUMPG	T2,SHFLOP	;NONE FIT EXACTLY, MOVE JOB ABOVE THE HOLE
	JUMPE	J,CHKSH4	;NONE FOUND - SYSTEM ERROR OR CORE FRAGMENTED
				; BY LOCKED SEGMENTS
	JUMPL	P1,NOTSHF	;THE ONE THAT FITS IS NOT SHUFFABLE NOW
	MOVE	R,JBTADR(J)	;SETUP SEGMENT RELOCATION
	JRST	SHFL		;ONE FITS AND IT CAN BE SHUFFLED
;HERE IF NO SHUFFLABLE JOB WAS FOUND-MEMORY IS FRAGMENTED DUE TO
; LOCKED JOBS OR MEMORY OF LINE

CHKSH4:	MOVE	T3,HOLEF	;TOP OF THIS HOLE
	SETZB	T4,HOLEF	;ASSUME NO HOLE AND SETUP TO
	PUSHJ	P,CORST2	; CALCULATE A BYTE POINTER TO 1ST K ABOVE HOLE
	MOVE	P1,T1		;MOVE BYTE POINTER TO P1 FOR HOLSRP
	SETZB	T1,P3		;FIND ANY UNOCCUPIED CORE
	PUSHJ	P,HOLSRP	;SEARCH FOR A HOLE ABOVE THE CURRENT ONE
	  POPJ	P,		;NONE-RETURN
	ADDI	T3,1(T4)	;HIGHEST ADDRESS IN THE HOLE
IFN FTLOCK,<
	CAMN	T3,HOLTOP##	;IS IT AT THE TOP OF UNLOCKED MEMORY?
>
IFE FTLOCK,<
	CAMN	P1,CORLST	;IS IT AT THE TOP OF MEMORY?
>
	POPJ	P,		;YES, RETURN
	MOVEM	T3,HOLEF	;NO, STORE ADDRESS OF TOP OF THE HOLE
	MOVEM	T4,HOLES	; AND THE SIZE OF THE HOLE
	JRST	CHKSHF		; AND TRY AGAIN

>				;END SHUFFLER
IFN FTLOCK!FTSHFL,<		;LOCK FEATURE OR SHUFFLER
SHFLOP:	SKIPN	R,JBTADR(J)	;JOB ABOVE HOLE STILL IN CORE?
	JRST	NOTSHF		;NO
	MOVSI	T1,SHF		;GET SHF BIT
	IORM	T1,JBTSTS(J)	;SET SHF SO JOB IS UN RUNNABLE ON SLAVE
	PUSHJ	P,ANYACT##	;YES ALL DEVICES FINISHED ? 
	  JRST	NOTSHF		;NO, GO SEE IF HOLE STILL THERE
SHFL:
IFN FTMS,<	EXTERN ANYRUN
	MOVSI	T1,SHF		;SET SHF BIT SO SLAVE WILL NOT
	IORM	T1,JBTSTS(J)	;TRY TO RUN THIS JOB.
	PUSHJ	P,ANYRUN	;IS SLAVE RUNNING THIS JOB?
	  JRST	NOTSHF		;YES, DO NOT SHUFFLE (SINCE SLAVE HARDWARE
>				; WOULD NOT GET CHANGED.
	HLRZ	T1,R		;YES, REASSIGN SAME AMOUNT OF CORE.
	PUSHJ	P,SCORE1##	;IN A LOWER POSITION IN CORE

NOTSH1:	SETZM	SHFWAT		;JOB SHUFFLED, CLEAR FLAG
	MOVSI	T1,SHF		;CLEAR SHUFFLE WAIT BIT IN CASE IT WAS ON
	ANDCAM	T1,JBTSTS(J)
	POPJ	P,


;JOB CANNOT BE MOVED BECAUSE IT HAS ACTIVE DEVICES OR NSHF BIT SET(DISPLAY,REALTIME)
; SO JOB CANNOT BY SHUFFLED AT THIS TIME


NOTSHF:
	SKIPN	HOLEF		;IS HOLE STILL THERE?
	JRST	NOTSH1		;NO

IFN FTSWAP,<
	EXTERN	FIT,FORCE
	MOVM	T1,FORCE
	CAME	J,FIT
	CAMN	J,T1
	JRST	NOTSH1
>

	MOVEM	J,SHFWAT	;SET SHUFFLE WAIT FLAG WITH JOB NO.
	POPJ	P,		;AND IO WILL STOP SOON
>				;END LOCK OR SHUFFLER
;HERE TO ASSIGN PHYSICAL CORE IN CORE OR ON THE DISK

	INTERN	CORE1A,CORGET

CORE1A:	NOSCHEDULE		;PREVENT JOB SCHEDULING
	PUSHJ	P,SAVE1##	;SAVE P1
	JUMPE	R,CORGET	;OLD ASSIGNMENT 0?
				; IF YES, DO NOT ATTEMPT TO RETURN OLD CORE
	MOVEI	P1,0		;CLEAR FOR CORSTG CALL
	PUSHJ	P,CORST0	;RETURN OLD CORE TO FREE STORAGE
;CORGET IS CALLED BY SWAPPER WHEN JOB IS ON DISC AND IS
;WANTED IN CORE.

CORGET:	SETZB	T3,R		;SET NEW ASSIGNMENT TO 0 AND DIST. MOVED
	JUMPE	T1,DIDLE1	;IS ZERO CORE BEING REQUESTED?
IFN FTLOCK,<
	EXTERN	SETLPR
	PUSHJ	P,SETLPR	;IF THIS IS THE JOB BEING LOCKED
	  JRST	CORGT1		;LET LOCK SPECIFY WHERE TO PUT IT
>
	PUSHJ	P,HOLSRC	;NO, SEARCH FOR HOLE BIG ENOUGH
	  JRST	BAKOLD		;NONE, GIVE BACK OLD AMOUNT
CORGT1:
	INTERN	FTTRACK
IFN FTTRACK,<
	EXTERN	LASCOR
	MOVEM	J,LASCOR	;LEAVE TRACKS FOR LAST JOB USING
				; PHYSICAL CORE ALLOCATION
				; (FOR DEBUGGING ONLY)
>
	MOVEM	T3,R		;SETUP NEW RELOC
	HRLM	T1,R		;AND NEW PROTECT.
	MOVEI	T4,(T1)		;HIGHEST REL ADR. BEING REQUESTED
	MOVEI	P1,1		;SET USE BITS IN CORE TABLE
	INTERN	FTLOCK
IFN FTLOCK,<
	EXTERN	LOCK
	HRRZ	T2,LOCK		;IF THIS IS THE JOB BEING LOCKED
	CAMN	T2,J		;INDICATE THAT THE CORE IT OCCUPIES
	MOVEI	P1,2		;IS NOT AVAILABLE FOR OTHER JOBS BEING LOCKED
>
	PUSHJ	P,CORSTG
	MOVE	T4,JBTADR(J)	;OLD CORE ASSIGNMENT
	JUMPN	T4,MOVCOR	;WAS THERE OLD MEMORY ASSIGNED?
				; NO,
IFN FTSWAP,<
	LDB	T2,IMGOUT##	;SIZE(IN K) OF SEG ON DISK TO BE SWAPPED IN
	LSH	T2,P2WLSH##	;CONVERT TO WORDS
>
IFE FTSWAP,<
	MOVEI	T2,0		;JOB HAS NO PREVIOUS VIRT. CORE(NON-SWAP SYS)
>
	MOVE	T4,R		;MAKE OLD ASSIGNMENT(T4) APPEAR TO START
				; AT SAME PLACE AS NEW ASSIGNMENT(FOR CLEARING)
	SOJA	T2,CLRCR1	;IF NEW CORE SIZE IS BIGGER THAN
				;OLD, CLEAR OUT INCREASE SO SECURITY WILL
				; BE MAINTAINED. T2 IS SIZE-1 OF OLD
				; ASSIGNMENT. -1 OF NO OLD ASSIGNMENT
;HERE WHEN FREE CORE TABLE DOES NOT HAVE ENOUGH ROOM FOR REQUEST

BAKOLD:
IFN FTSWAP,<
	EXTERN	XPAND
	PUSHJ	P,XPAND		;TELL SWAPPER TO SWAP OUT
>
IFE FTSWAP,<			;(DO NOT DELETE DORMANT SEGS IF SWAPPING SYSTEM
				; SINCE SWAPPER DOES IT TOO)

	IFE	FT2REL,<
	SOS	(P)		;SET FOR ERROR RETURN AND GET BACK LD CORE
	>
	IFN	FT2REL,<
	EXTERN	FRECOR
	PUSHJ	P,FRECOR	;TRY TO DELETE 1 DORMANT HIGH SEGMENT,
				; IF REQUEST DOES NOT EXCEED FREE CORE+DORMANT SEGS
	  SOSA	(P)		;ERROR RETURN-NOT ENOUGH CORE, GET OLD AMOUNT BACK
	JRST	CORGET		;1 DORMANT SEG DELETED, TRY REQUEST AGAIN
	>
>
BKOLD1:	HLRZ	T1,JBTADR(J)	;GET BACK OLD CORE.
	JRST	CORGET
;MOVE OLD CORE TO NEW AREA

MOVCOR:	CAIN	T3,(T4)		;IS NEW CORE IN SAME PLACE AS OLD?
	JRST	CLRCOR		;YES, DO NOT MOVE IT,CLEAR IF INCREASE
	HLRZ	T2,T4		;LENGTH OF OLD CORE
	CAILE	T2,(T1)		;IS OLD CORE LESS THAN NEW?
	HRRZ	T2,T1		;NO, MOVE THE SHORTENED NEW CORE
IFN FTTIME,<
	EXTERN	SHFWRD
	ADDM	T2,SHFWRD	;INCREMENT TOTAL NO. WORDS SHUFFLED
>
	ADD	T2,T3		;ADD IN NEW RELOC.
	MOVE	P1,T3		;DEST.=NEW RELOC.
	HRL	P1,T4		;SOURCE=OLD RELOC.
IFN FTMEMPAR,<			;MEMORY PARITY?
;THE FOLLOWING SYMBOLS ARE USED BY THE APR MEMORY PARITY ERROR INTERRUPT
; ROUTINE WHICH HAPPENS AT A HIGH PRIORITY PI LEVEL

	INTERN	BLTINS		;VALUE OF PC ON PARITY INTERRUPT DURING BLT
	MOVEM	J,.C0LSB##	;LAST SEG (HI OR LOW) TO BE BLTED
	XP	BLTAC,P1	;AC USED AS BLT POINTER - MUL. DEF GLOBAL IF DOES
				; NOT AGREE WITH APR INTERRUPT VALUE
BLTINS:		;ADDRESS OF BLT INSTR.
>
	BLT	P1,(T2)		;MOVE CORE TO NEW ASSIGNMENT

;CLEAR INCREASE IF NEW CORE IS BIGGER THAN OLD

CLRCOR:	HLRZ	T2,T4		;OLD CORE SIZE-1
CLRCR1:	CAMG	T1,T2		;IS NEW CORE SIZE-1 VREATER THAN OLD CORE SIZE-1
	JRST	DIDLE		;NO, DO NOT CLEAR ANY CORE
IFN FTTIME,<
	MOVE	P1,T1		;NEW CORE SIZE
	SUB	P1,T2		;LESS OLD CORE SIZE
	ADDM	P1,CLRWRD##	;ACCUMULATE NO. OF WORDS CLEARED
>
	ADDI	T2,2(R)		;YES, OLD SIZE-1+NEW RELOC+2=2ND T3 TO CLEAR
	ADDI	T1,(R)		;NEW SIZE-1+NEW RELOC=LAST T3 TO CLEAR
	SETZM	-1(T2)		;CLEAR FIRST WORD
	HRLI	T2,-1(T2)	;SET LH TO FIRST ADR. TO CLEAR
	BLT	T2,(T1)		;CLEAR THE INCREASE PORTION
;IF THE SHUFFLED JOB IS IN EXEC MODE, ITS DUMP ACS
;(P,R SAVED IN JOB DATA AREA) MUST BE
;ALTERED BY DISTANCE CORE WAS MOVED

;IF THE SHUFFLED JOB IS CURRENT JOB, THE SOFTWARE STATE OF
;THE MONITOR(IE SOFTWARE INFO OF JOB) MUST BE ALTERED BY AMOUNT
;CORE WAS MOVED

	EXTERN	SYSSIZ

DIDLE:
IFN FTPDBS,< ;IF WE SWAP PDBS WE MAY HAVE JUST GOTTEN ONE INTO CORE
	JUMPL	J,DIDLE1	;NO JOBDATA AREA IN PDB
> ;END FTPDBS
	SUBI	T3,(T4)		;DISTANCE JOB WAS MOVED(DEST.-SOURCE)
	MOVE	T1,JOBPC##(R)	;GET PC IN JOB DATA AREA
	CAMN	J,JOB##		;IS THIS CURRENT JOB?
	MOVE	T1,USRPC##	;YES, PC IN PROTECTED SYSTEM AREA
IFN FT2REL,<
	EXTERN	JOBMAX
	CAILE	J,JOBMAX	;IS THIS A HIGH SEGMENT?
	JRST	DIDLE1		;YES.  DO NOT ALTER JOBREL
>

	EXTERN	JOBREL

	HLRZM	R,JOBREL(R)	;UPDATE JOBREL SO USER DOING E COMMAND AFTER A CORE
				; COMMAND WON'T GET CONFUSED
	TLNE	T1,USRMOD	;NO, IS JOB IN USER MODE?
	JRST	DIDLE1		;YES, DO NOT ALTER DUMP ACS
				; BECAUSE THEY ARE THE USERS(OR HIGH SEG)
	HRRZ	T1,JOBDPD##(R)	;NO, CHECK DUMP P TO SEE IF IN EXEC CORE
				; (PDL OV) INSTEAD OF USER CORE
	CAMG	T1,SYSSIZ	;IS IT IN ABS. EXEC CORE?
	JRST	DIDLE0		;YES
	ADDM	T3,JOBDPD##(R)	;NO. ALTER DUMP P BY DIST. OF MOVE
DIDLE0:
	ADDM	T3,JOBDPG##(R)	;AND ALTER R BY DIST. MOVED
DIDLE1:	CAME	J,JOB##		;IS THIS CURRENT JOB?
	JRST	DIDLE3		;NO, DO NOT ALTER STATE OF MONITOR
	MOVE	T1,SYSSIZ	;DONT CHANGE P IF LIST
	CAIG	T1,(P)		;IS IN SYSTEM
	ADD	P,T3		;YES, ALTER PUSH DOWN POINTER BY AMOUNT OF MOVE
DIDLE3:	SKIPE	R		;GETTING CORE?
	PUSHJ	P,IICLNK##	;YES
	SKIPN	R		;GIVING UP CORE?
	PUSHJ	P,DICLNK##	;YES
	MOVEM	R,JBTADR(J)	;STORE NEW CORE ASSIGNMENT(LOW OR HIGH SEG)
	CAMN	J,JOB##		;CURRENT JOB?
	PUSHJ	P,SETREL	;SETUP RELOCATION REGISTERS
				; INFORMATION FOR HIGH AND LOW SEGS FOR CURRENT JOB
IFN FT2REL,<
	EXTERN	CURHGH
	PUSHJ	P,CURHGH	;CHECK TO SEE IF THIS CORE ASSIGNMENT IS FOR
				; HIGH SEG WHICH CURRENT USER MAY ALSO BE USING
				; IF YES, RESET HARDWARE AND SOFTWARE RELOC INFO.
				; RETURN WITH J PRESERVED, R SET TO RELOC
				; OF SEG WHICH HAS JUST HAD CORE REASSIGNED

>
CORPRM:	SETZB	T1,HOLEF	;CLEAR HOLE FLAG
	PUSHJ	P,HOLSRC	;IS THERE A NON-ZERO HOLE?
	JRST	COROK		;NO
	ADDI	T3,1(T4)	;YES, FORM ADR. OF JOB JUST ABOVE HOLE
	CAME	P1,CORLST##	;IS HOLE AT TOP OF MEMORY
	MOVEM	T3,HOLEF	;NO, FLAG WITH ADDRESS OF JOB ABOVE HOLE
	MOVEM	T4,HOLES	;SAVE THE SIZE OF THE HOLE

IFN FTSWAP,<
	EXTERN	BIGHOLE
	MOVEI	T1,-1		;FIND BIGGEST HOLE
	PUSHJ	P,CORHOL	;ALWAYS GET ERROR RETURN
	ASH	P2,W2PLSH##	;CONVERT TO 1K BLOCKS
	MOVEM	P2,BIGHOLE
>
	SCHEDULE
	JRST	CPOPJ1##	;SKIP RETURN(UNLESS ERROR)
COROK:	SETZM	HOLES		;NO HOLES IN MEMORY
	SETZM	BIGHOLE
	JRST	CPOPJ1##	;SKIP RETURN
;ROUTINE TO FIND HOLE BIG ENOUGH FOR REQUEST
;CALL:	MOVE	T1,HIGHEST REL. ADR. ASKING FOR
;	PUSHJ	P,HOLSRC
;	RETURN1			;NO HOLES BIG ENOUGH
;	RETURN2			;P1 BYTE SET TO LAST BLOCK+1 IN HOLE
;				;T3 SET TO ADDRESS OF FIRST BLOCK IN HOLE
;				;T4 SET TO HIGHEST REL. LOC. IN THAT HOLE
;				;P2=LARGEST HOLE SEEN
;USES T2

	INTERN	HOLSRT,HOLSRP,HOLSRC

HOLSRC:	MOVEI	P3,0		;LOOK FOR EMPTY CORE ONLY
HOLSRT:	MOVE	T3,SYSSIZ	;STARTING AT SYSSIZ
	MOVE	P1,CORE2P##	;BYTE POINTER TO FIRST BIT-1
HOLSRP:
IFN FTSWAP,<
	MOVEI	P2,0		;LARGEST HOLE SO FAR=0
>
CORHOL:	TDZA	T4,T4		;START T4 AT 0 AND SKIP

CORHO0:	ADDI	T4,PAGSIZ##	;INCREMENT HIGHEST REL LOC.
CORHO1:	CAMN	P1,CORLST##	;BYTE POINTER TO 1ST NON-EXISTANT BLOCK
	POPJ	P,		;NO MORE CORE TO SEARCH
	ILDB	T2,P1		;GET NEXT CORE USE BIT
	ADDI	T3,PAGSIZ##	;INCREMENT ADDRESS OF BLOCK
	CAIN	T2,(P3)		;COUNT IT IF ITS THE RIGHT TYPE
	JRST	CORHO0		;IT IS
	JUMPE	T2,CORHO0	;IS THIS BLOCK IN USE?
	JUMPE	T4,CORHO1	;YES, HAVE ANY FREE BLOCKS BEEN SEEN YET?
IFN FTSWAP,<
	CAMLE	T4,P2		;YES, BIGGEST SO FAR?
	MOVEM	T4,P2		;YES, SAVE IN T1.
>
	CAMG	T4,T1		;YES, IS THIS HOLE EQUAL OR GREATER THAN REQUEST?
	JRST	CORHOL		;NO, KEEP LOOKING FOR HOLES
	SUBI	T3,PAGSIZ##(T4)	;YES, SET T3 TO FIRST BLOCK IN HOLE
	SOJA	T4,CPOPJ1	;SET T4 TO HIGHEST REL. LOC.
				; AND RETURN
;ROUTINE TO SET AND CLEAR CORE USE TABLE
;CALL:	MOVEI	P1,2		;TO INDICATE LOCKED JOB
;	MOVEI	P1,1		;TO INDICATE IN USE
;	MOVEI	P1,0		;TO INDICATE FREE
;BIT 33=1 OF P1 IF ONLY A CHANGE OF STATE
; OF ASSIGNED CORE (CORTAL NOT TO BE CHANGED)
;	MOVE	T3,ADDRESS OF FIRST BLOCK TO SET CLEAR
;	MOVE	T4,HIGHEST REL. LOC. IN USER AREA

	EXTERN	TPOPJ
	EXTERN	CTNBPW,CTNBSA,COREP,CPOPJ

CORST0::HRRZ	T3,R		;ABS .ADR OF ORIGIN OF HI OR LOW SEG
	HLRZ	T4,R		;HIGHEST REL. LOC IN HI OR LOW SEG
CORSTG:	ASH	T4,W2PLSH##	;CONVERT TO NO. OF BLOCKS-1
	ADDI	T4,1		;NO. OF BLOCKS

CORST1:
	PUSH	P,T1		;SAVE HIGHEST LOC. BEING REQUESTED
	SKIPE	P1		;UPDATE NO OF FREE BLOCKS
	MOVNS	T4		;DECREASE IF SETTING BITS
IFN FTLOCK,<			;LOCK UUO FEATURE?
	TRNN	P1,4		;IS THIS JUST A CHANGE OF STATE OF ASSIGNED CORE?
				; (LOCKED TO UNLOCKED)
>
	ADDM	T4,CORTAL##	;INCREASE IF CLEARING,DECREASE IF SETTING BITS

CORST2:			;LOKCON MAY ENTER HERE TO COMPUTE A BYTE PTR. IF SO, T4=0
	HRRZ	T1,T3		;ADDRESS OF FIRST BLOCK
	ASH	T1,W2PLSH##	;FORM BYTE POINTER TO BIT-1
	IDIVI	T1,CTNBPW	;T1=WORD,T2=BIT
	ADD	T1,COREP	;FORM BYTE POINTER
	MOVNS	T2
	ADDI	T2,CTNBPW
	ASH	T2,CTNBSA	;MULTIPLY BY NUMBER OF BITS PER ENTRY
				;MUST BE A POWER OF TWO THAT DIVIDES ^D36
	DPB	T2,[POINT 6,T1,5]
IFN FTLOCK,<
	JUMPE	T4,CPOPJ	;RETURN IF BYTE POINTER IS ALL THATS NEEDED
>
	MOVMS	T4		;GET MAG. OF NO. OF BLOCKS INVOLVED
	IDPB	P1,T1		;SET OR CLEAR EACH USE BIT
	SOJG	T4,.-1
	JRST	TPOPJ		;RESTORE T1, AND POPJ

SUBTTL	UUOCON - UUO HANDLING ROUTINES

;SUBROUTINE TO DO PROCESSOR DEPENDANT PORTION OF THE JOB PEEK UUO
;CALLING SEQUENCE:
;	MOVE	T4,JBTADR FOR SOURCE SEGMENT
;	MOVE	P3,JBTADR FOR DESTINATION SEGMENT
;	MOVE	P2,NUMBER OF WORDS TO TRANSFER
;	PUSHJ	P,JOBPKD
;	ALWAYS RETURN HERE
IFN FTDAEM,<

	INTERN	JOBPKD

JOBPKD:	HRLZ	T2,T4		;LH T2=ADDR OF SOURCE SEGMENT IN CORE
	HRR	T2,P3		;RH T2=ADDR OF DESTINATION SEGMENT IN CORE
	ADD	T1,T2		;XWD SOURCE,DESTINATION
	ADDI	P2,(T1)
	BLT	T1,-1(P2)
	POPJ	P,

>	;END IFN FTDAEM

;SUBROUTINE TO INSURE THAT A DUMP MODE COMMAND LIST
; WILL NOT CAUSE A LOOP
;CALLED BY DMPIO BEFORE DISPATCHING TO DEVICE HANDLER
;IF POTENTIAL LOOP IS DETECTED, PRINT "ADDRESS CHECK"
DMPEV::	PUSHJ	P,SAVE1##
	PUSH	P,T1		;SAVE DISPATCH ADDRESS
	PUSH	P,M		;SAVE M
	SOS	M		;SET M FOR GETWRD
	MOVEI	P1,10000	;GUARANTEE NO LOOPS
DMPEV1:	PUSHJ	P,GETWD1##	;READ AN IO WORD
	JUMPE	T1,DMPEV2	;TERMINATION WORD?
	TLNN	T1,-1		;NO, JUMP WORD?
	HRRI	M,-1(T1)	;YES, FOLLOW JUMP WORD
	SOJG	P1,DMPEV1	;READ NEXT IO WORD
	JRST	ADRERR##	;THIS COMMAND LIST LOOPS

DMPEV2:	POP	P,M
	JRST	TPOPJ##		;RESTORE DISPATCH ADDRESS
				; AND EXIT
	LIT
KAEND:	END