Google
 

Trailing-Edge - PDP-10 Archives - dec-10-omona-u-mc9 - datman.mac
There are 9 other files named datman.mac in the archive. Click here to see a list.
TITLE DATMAN - DATA BASE MANAGER  V070
SUBTTL D BLACK/DAL/JBS  11 JAN 77
	SEARCH	F,S
	$RELOC
	$HIGH
;***COPYRIGHT 1973,1974,1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
XP VDATMN,070

	ENTRY	DATMAN

DATMAN::		;CAUSE DATMAN TO LOAD IF IN LIBRARY FILE

XP LISTSN,1		;CAUSE S.MAC AND F.MAC TO BE LISTED HERE
			; (USED TO BE IN COMMON WHICH IS NOW TOO BIG).


REPEAT 0,<
The DATA BASE MANAGER contains both subroutines to manipulate
monitor's data base and formats of various components of the data base.
The DATA BASE MANAGER should be the only module which modifies the data base;
all other modules should call DATMAN.
This scheme has a number of advantages:

1. It provides a good chance for comments.
2. It provides good conventions for future growth.
3. It provides good locality.
4. It helps reentrancy by having only one module maintain impure code.

DATMAN will also control writing in users' core too.
PROCESS and SEGMENT are important components in the data base
being introduced at this time.
A SEGMENT is one logical collection of data, either program data
or code, and is the building block of a program. Segments are really
the same as previously.
A PROCESS is a virtual machine;
it has a hardware state associated with it: a virtual memory, a processor,
typically one PC, a stack, etc. A process's virtual memory will
contain a number of segments. Several processes may run either
serially or in parallel as one overall program or user.
Monitor data will be organized on a per segment and a per process basis.
Part of per segment and part of per process data must be resident,
other parts could be swappable; the data breaks up
into four components. The following abbreviations and definitions will be used:

PRB	Process Resident Block - the resident process information.
	This will be very small, about 8 or 12 words.

PDB	Process Data Block - the not necessarily resident (swappable) process data.
	This will be most of the process data and may grow to fill a page or more.

SRB	Segment Resident Block - the resident segment information.
	This will be very small, about 8 or 12 words.

SDB	Segment Data Block - the not necessarily resident segment data.
	This may grow to fill a page or more.
Conventions about symbols:

symbols will consist of a three letter prefix and a three letter suffix.
The prefix will determine to what type of data base component the entry belongs,
and the particular usage of the entry.
For example, a word entry in the PDB would be .PDxxx.
The suffix is a three letter mnemonic describing the entry. Thus
the PDB entry SIZ containing the size of the PDB
would be .PDSIZ.
DATMAN is organized in the following manner:

First are the definitions of the various data base components.
These will be in alphabetical order so they can be found easily.

Second are subroutines for manipulating the data base,
grouped by function. Code should go down the page,
as in 5 series monitor conventions, until concern for locality
becomes more important.
>	;END REPEAT 0
	SUBTTL	PDB LOGIC

IFN FTPDBS,< ;ALL THIS CODEIS ONLY NEEDED FOR THE SWAPPING CASE
;SUBROUTINE TO CREATE A PDB.
;CALL WITH:
;	MOVEI	J,PROCESS-NUMBER
;	MOVE	U,ADDRESS OF LDB
;	PUSHJ	P,CREPDB
;	  RETURN HERE IF NO VIRT. MEMORY LEFT
;	RETURN HERE WITH PDB. IF W = 0 THE THE PDB IS ON THE DISK AND
;	  THE CALLER MUST FIGURE OUT SOME WAY TO GET IT IN CORE AND
;	  RETRY THIS ROUTINE.
;AC'S WHICH RETURN A VALUE:
;	W = ADDRESS OF IN CORE PDB OR 0
;AC'S WHICH ARE PRESERVED:
;	J = JOB #
;	R = RELOCATION
;	U = LDB FOR CHECK WORD
;	S,F,M AND P1 TO P4 ARE PRESERVED BUT NEED NOT CONTAIN
;	USEFUL INFORMATION ON THE CALL.
;AC'S T1,T2,T3,T4 ARE KNOWN TO BE CLOBBERED.
CREPDB::PUSHJ	P,SAVE4##	;SAVE P1-P4
	PUSH	P,U		;SAVE OTHER AC'S 
	PUSH	P,M
	PUSH	P,F
	PUSH	P,S
	MOVN	J,J		;J = PDB NUMBER
	SETZM	W		;NO PDB YET.
	SKIPE	R,JBTADR##(J)	;DOES PDB  EXIST IN CORE?
	JRST	CREPD1		;YES--CAN HAPPEN IF COMCON HAD TO
				; DELAY A COMMAND.
	MOVEI	T1,PDBWDS##	;SIZE OF PDB ROUNDED UP TO A PAGE BOUNDARY
	PUSHJ	P,CORE1##	;GO GET SOME STORAGE SPACE
	  JRST	CREPDX		;NO MORE SPACE. NOT EVEN ON DISK.
CREPD1:	AOS	-4(P)		;NOTE WE HAVE CORE SOMEPLACE
	JUMPE	R,CREPDX	;EXIT IF SPACE IS ON THE DISK.
	MOVEM	R,JBTADR##(J)	;REMEMBER LOCATION OF PDB
	MOVS	T1,TIME##	;LH(T1) = TIME OF DAY
	HRR	T1,U		;RH(T1) = ADDRESS OF LDB
	MOVEM	T1,.PDCHK##(R)	;STORE AWAY THE CHECK WORD
	HRRZ	W,R		;W = ADDRESS OF PDB
CREPDX:	MOVM	J,J		;RESTORE JOB #
	MOVE	R,JBTADR##(J)	;RESTORE ADDRESS OF JOBDAT
	POP	P,S
	POP	P,F
	POP	P,M
	POP	P,U
	POPJ	P,		;RETURN




;STILL IN FTPDBS
;SUBROUTINE TO KILL A PDB
;CALL WITH:
;	MOVEI	J,JOB-NUMBER
;	PUSHJ	P,KILPDB
KILPDB::MOVN	J,J		;J - PDB NUMBER
	PUSHJ	P,SEGSIZ##	;GET SIZE OF SEGMENT
	PUSHJ	P,ZERSWP##	;GIVE BACK ANY DISK SPACE
	SETZM	T1		;GIVE BACK ANY SPACE IN
	MOVE	R,JBTADR##(J)	;R = POINTER TO CORE TO GIVE BACK
	PUSHJ	P,CORE1##	; MAIN MEMORY
	  STOPCD .,STOP,CDW,	;CORE1 DOSN'T WORK
	MOVM	J,J		;RESTORE J
	POPJ	P,		;RETURN

;STILL IN FTPDBS
;SUBROUTINES TO MODIFY A PDB

;SUBROUTINE TO STORE QUANTUM RUN TIME IN THE PDB. IF PDB IS ON THE
; DISK FLAG IT SO TIME WILL BE RESET ON SWAPIN.
;CALL WITH:
;	MOVE	T1,QUANTUM-TIME
;	MOVE	J,PROCESS HANDLE
;	PUSHJ	P,SETQNT
;	RETURN HERE T1 AND W CLOBBERED ALL ELSE PRESERVED
SETQNT::PUSHJ	P,FNDPDB	;LOCATE THE PDB
	  JRST	SETQN1		;ON THE DISK
	.DPB	T1,PDYQNT##	;STORE THE NUMBER
	POPJ	P,		;RETURN
SETQN1:	MOVEI	T1,JS.RQR	;FLAG TO RESET RUN TIME
	IORM	T1,JBTSTS##(J)	;STANDARD PLACE FOR SUCH THINGS
	POPJ	P,		;RETURN. WE TRIED AS BEST WE COULD

> ;END FTPDBS

;SUBROUTINE TO GET A WORD OUT OF A PDB. CALLABLE ONLY FROM UUO LEVEL
;CALLED WITH:
;	J = .C0JOB = CALLERS PROCESS HANDLE
;	T2 = PROCESS NUMBER OF DESIRED PROCESS (POSITIVE NUMBER)
;	T3 = INDEX INTO PDB. (SMALL POSITIVE NUMBER)
;	PUSHJ	P,PDBWRD
;	RETURN HERE WITH WORD IN T1. IF THE PDB DOES NOT EXIST THEN
;	       ZERO IS RETURNED.
 
;CLOBBERS J,U,F,R,T1-T4
PDBWRD::MOVE	T1,T2		;GET POINTER TO PDB
	PUSHJ	P,FPDBT1	; ..
	  JRST	PDBWD1		;NOT IN CORE TRY HARDER
	ADD	T1,T3		;SELECT CORRECT WORD
	MOVE	T1,(T1)		;LOAD INTO T1
	POPJ	P,		;AND RETURN

;HERE IF PDB IS NOT IN CORE

IFE FTPDBS,<
PDBWD1:	SETZM	T1		;IF THE PDB IS NOT IN CORE AND WE
	POPJ	P,		; DO NOT SWAP THEN RETURN ZERO
>

IFN FTPDBS,<	;IF WE SWAP PDB'S THE STUFF COULD BE ON THE DISK
PDBWD1:	SETZM	T1		;IN CASE NO PDB AT ALL
	MOVSI	T4,JNA		;TEST TO SEE IF THERE IS A PDB
	TDNN	T4,JBTSTS##(T2)	; FOR THIS PROCESS NUMBER
	POPJ	P,		;NOT TODAY. RETURN ZERO

;HERE IF PDB IS ON THE DISK

	PUSHJ	P,SCWAIT##	;WAIT FOR SWAPPER CHANNEL
	PUSH	P,T3		;SAVE OFFSET
	MOVE	T3,PDIOWD##	;LOCATION OF THE PDB
	PUSHJ	P,REDPDB	;GO READ THE PDB
	POP	P,T1		;RESTORE OFFSET
	MOVE	T1,PDBUFF##(T1)	;GET THE WORD
	PJRST	SCFREE##	;RETURN THE CHANNEL

>; END IFN FTPDBS
IFN FTPDBS,< ;DO WE SWAP PDB'S?
;SUBROUTINE TO READ A PDB INTO A GIVEN LOCATION
;CALL WITH:
;	T3 = IOWD FOR BUFFER
;	T2 = DESIRED JOB'S PDB (SMALL POSITIVE NUMBER)
;	PUSHJ	P,SCWAIT	;GET SC RESOURCE
;	PUSHJ	P,REDPDB
;	RETURN HERE WITH PDB IN CORE
;CLOBBERS S,F,U,T1-T4,J
;REDPDB RETURNS WITH THE SC RESOURCE

REDPDB::MOVE	T1,T2		;SEE IF PDB IS IN CORE
	PUSHJ	P,FPDBT1	; ..
	  JRST	REDPD1		;NO--THIS IS THE NORMAL CASE
	AOS	T3		;YES--THE PDB WAS SWAPPED INTO
	MOVE	T2,(T1)		; CORE BECAUSE WE CALLED THE
	MOVEM	T2,(T3)		; SCHEDULER WITH THE PUSHJ TO
	AOBJN	T3,.-2		; SCWAIT. THIS SLOW BLT WILL
	POPJ	P,		; AVOID ANY RACE CONDITIONS.

;HERE IF THE PDB IS ON THE DISK AS EXPECTED

REDPD1:	MOVN	J,T2		;J GETS PDB POINTER
;	PJRST	REDSEG		;READ THE SEGMENT

;STILL UNDER FTPDBS
;SUBROUTINE TO READ A SEGMENT INTO CORE. 
;CALL WITH:
;	J = SEGMENT NUMBER
;	T3 = IOWD
;	PUSHJ	P,REDSEG
;	RETURN HERE WITH SEGMENT READ
;CALLER MUST HAVE THE SC RESOURCE AT THE TIME OF THE CALL
;CLOBBERS J,U,F,S,R,T1,T2,T3,T4
REDSEG::MOVEI	S,0		;INDICATE READING
	AOS	T3		;SQGO WILL SUBTRACT 1 AND WE WILL STILL
				; HAVE AN IOWD.
	HLRZ	T1,JBTSWP##(J)	;T1 GETS SWAPPING POINTER
	MOVEM	T1,SERA##	;STORE FOR SWPSER
	MOVEM	T3,SQREQ##	;STORE POINTER
	MOVEM	T3,ESQREQ##	;AGAIN INCASE OF ERROR
	PUSHJ	P,SQGO##	;START UP THE I/O
	MOVE	J,.C0JOB##	;GET CURRENT JOB NUMBER
	DPB	J,PJOBN##	;MARK HIM AS THE OWNER OF THE SWAPPING
				; DDB. THAT IS WHY WE HAVE THE SC RESOURCE
	MOVE	R,JBTADR##(J)	;MAKE JOBDAT ADDRESSABLE
	PUSHJ	P,WAIT1##	;WAIT FOR I/O TO GET DONE
	SETZB	T1,SERA##	;RESTORE SWAPPING DDB TO THE NULL JOB
	DPB	T1,PJOBN##	; ..
	POPJ	P,		;ALL DONE


> ;END FTPDBS
;SUBROUTINE TO FIND A PDB OR HALT
;CALL WITH:
;	MOVE	J,PROCESS-NUMBER
;	PUSHJ	P,FNPDBS
;	RETURN HERE WITH W POINTING TO A PDB
;
FNDPDS::
FNPDBS::PUSHJ	P,FNDPDB	;FIND THE PDB
	  STOPCD CPOPJ##,DEBUG,NPJ, ;++NO PDB FOR JOB
	POPJ	P,


;SUBROUTINE TO FIND PDB FOR PROCESS IN T1
;	PUSHJ 	P,FPDBT1
;	  HERE IF NO PDB
;	HERE WITH T1 POINTING TO PDB
FPDBT1::PUSH	P,J		;SAVE J AND W
	PUSH	P,W		; ..
	HRRZ	J,T1		;COPY PDB HANDLE
	PUSHJ	P,FNDPDB	;FIND THE PDB
	  SOS	-2(P)		;CAUSE NON-SKIP RETURN
	MOVE	T1,W		;COPY CORE ADDRESS
	POP	P,W		;RESTORE AC'S
	JRST	JPOPJ1##	;RETURN
;SUBROUTINE TO FIND A PDB
;CALL WITH:
;	MOVE	J,PROCESS-NUMBER
;	PUSHJ	P,FNDPDB
;	  RETURN HERE IF NO PDB (W = 0)
;	RETURN HERE WITH W POINTING TO PDB

IFN FTPDBS,< ;IF PDB'S ARE SWAPPED
FNDPDB::MOVEI	W,PDBPRO##	;POINT TO PROTOTYPE PDB
	PJUMPE	J,CPOPJ1##	;ALL DONE IF NULL JOB
	HRRZ	J,J		;MAKE SURE LH(J)=0
IFN FTHALT,<
	CAILE	J,JOBMAX##	;SKIP IF IN RANGE
	STOPCD	.+1,DEBUG,PNB,	;PROCESS NUMBER BAD
> ;END FTHALT
	MOVN	W,J		;W = PDB NUMBER
	HRRZ	W,JBTADR##(W)	;W = PDB ADDRESS
	JUMPN	W,CPOPJ1##	;RETURN IF VALID NUMBER
	POPJ	P,		;NO-PDB RETURN

> ;END FTPDBS


IFE FTPDBS,<

FNDPDB::PUSH	P,T1		;SAVE T1
	PUSHJ	P,LGJPR1	;SEE IF A LEGAL PROCESS (INCLUDING ZERO)
	  JRST	TPOPJ##		;NOT, LOSE
	HRRZ	W,JBTPDB##(J)	;GET PDB ADDRESS
	JUMPN	W,TPOPJ1##	;IF W IS NON-ZERO GIVE THE SKIP RETURN
	JRST	TPOPJ##		; ELSE FAIL

> ;END FTPDBS
	SUBTTL	ROUTINES TO REFERENCE USER CORE

;ROUTINE TO GET WORD FROM USER AREA AT UUO LEVEL - EITHER SEGMENT
;CALL:	MOVE R,XWD PROTECTION,RELOCATION FOR LOW SEG
;	HRR M,USER ADR.
;	PUSHJ P,GETWDU
;	RETURN ONLY IF ADDRESS OK, WORD IN T1, ABS. ADR IN T2

;	IF OUT OF BOUNDS, PRINT ILL UUO AND STOP JOB


GTWST2::PUSH	P,T2		;SAVE T2 ACROSS CALL TO GETWDU
	PUSHJ	P,GETWDU	;GET THE WORD
	JRST	T2POPJ##	;RESTORE T2 AND RETURN

GETWD1::HRRI	M,1(M)		;INCREMENT M BEFORE PICKING UP WORD
GETWDU::
	PUSHJ	P,CPUJOB##
	PUSHJ	P,GETWRD	;GET THE WORD AND CHECK IF LEGAL
	  JRST	UADERR##	;ADR. NOT IN LOW OR HIGH SEG, PRINT ERROR
	POPJ	P,		;OK RETURN, T1=WORD, T2=ABS. ADR.



;ROUTINE TO STORE T1 IN USER SHADOW ACS.
;MUST BE CALLED FROM UUO LEVEL WITH R SETUP
;ALSO R IN INDEX FIELD OF M


STOTC1::AOSA	(P)		;SKIP RETURN
RTM2::MOVNI	T1,2		;RETURN -2 TO USER
STOTAC::PUSH	P,M		;SAVE M
	LDB	M,PUUOAC##	;GET USER'S AC
	PUSHJ	P,PUTWDU	;STORE T1 IN USER'S AC
	JRST	MPOPJ##		;RESTORE M AND RETURN
;ROUTINE TO RE-LOAD AC T1 FROM USER'S AC ON A CALLI OR
;THE LIKE, IN CASES WHERE T1 HAS BEEN DESTROYED.
;CALL:	MOVE R,[XWD PROT,RELOC FOR LOW SEG]
;	MOVE J,JOB NUMBER
;	PUSHJ P,GETTAC
;	ALWAYS RETURN HERE (UERROR IF NOT IN CORE)
;				;AC NOW IN T1


GETTAC::LDB	T1,PUUOAC##	;GET USER'S AC NUMBER
	HRR	M,T1		;PROVIDE AS ADDRESS TO READ
	PUSHJ	P,GETWDU	;GET THE AC
	POPJ	P,		;RETURN

;ROUTINE TO GET 1 WORD FROM USER ARE WHICH CAN BE IN LOW OR HIGH SEG
;CALL:	MOVE R,[XWD PROT,RELOC FOR LOW SEG]
;	MOVE J,JOB NUMBER
;	HRR M,USER ADDRESS(IE BEFORE RELOCATION)
;	PUSHJ P,GETWRD
;	  ERROR RETURN ADDRESS OUT OF BOUNDS
;	OK RETURN, CONTENTS IN AC T1
;CAN BE CALLED AT CLOCK OR UUO LEVEL
;CALLED FROM E COMMAND,INIT,OPEN AND CALL UUOS


GETWR1::HRRI	M,1(M)		;INCREMENT M BEFORE PICKING UP WORD
GETWRD::TLZ	M,37		;SET RELOCATION FOR INDIRECTION
IFN FTKI10!FTKL10,<
IFN FTVM,<
	PUSHJ	P,FLTSX##	;SEE IF LEGAL ADR WHICH WILL PAGE-FAULT
	  POPJ	P,		;BAD ADR-ERROR RETURN
>
	PUSHJ	P,TSTREL##	;DON'T RELOCATE IF THIS IS A KI10
>
	TLO	M,R
	HLRZ	T1,R		;LARGEST REL LOC IN LOW SEG
	CAIGE	T1,(M)		;IS ADR. IN LOW SEG?
IFN FT2REL,<
	JRST	HGHWRD##	;NO, CHECK IF IN HIGH SEG(ERROR RET IF NO)
>
IFE FT2REL,<
	POPJ	P,		;NO, ERROR RETURN
>
IFN FTKI10!FTKL10,<
	PUSHJ	P,TSTREL##	;SEE HOW TO RELOCATE
	SKIPA	T1,@M		;KA10 OR SHADOW ACS
>
	EXCTUX	<MOVE	T1,@M>	;YES, GET IT FROM THE LOW SEGMENT
	JRST	CPOPJ1##	;AND SKIP RETURN
;ROUTINE TO PUT A WORD INTO A USER'S AREA AT UUO LEVEL-EITHER SEGMENT
;CALL:	MOVE	R,XWD PROTECTION, RELOCATION FOR LOW SEGMENT
;	HRR	UUO,USER'S ADDRESS
;	MOVE	T1,WORD TO STORE
;	PUSHJ	P,PUTWDU
;	RETURN ONLY IF ADDRESS OK.
;
;PRESERVES ALL ACS EXCEPT M.


PUTWD1::HRRI	M,1(M)		;INCREMENT M BEFORE STORING WORD
PUTWDU::PUSH	P,J		;SAVE J
	PUSHJ	P,CPUJOB##
	PUSHJ	P,PUTWRD	;STORE THE WORD
	  JRST	UADERR##	;A LOSER
	JRST	JPOPJ##		;A WINNER, RESTORE J AND RETURN

;HERE TO STORE A WORD IN USER'S AREA AT UUO OR CLOCK LEVEL

PUTWR1::HRRI	M,1(M)		;INCREMENT BEFORE STORING WORD
PUTWRD::
IFN FTVM,<
	PUSHJ	P,FLTSX##	;SEE IF LEGAL ADR WHICH WILL PAGE-FAULT
	  POPJ	P,		;BAD ADR
>
	PUSH	P,S		;SAVE S
	MOVE	S,T1		;SETUP S WITH WORD TO BE DEPOSITED
	PUSH	P,T1		;SAVE T1
	TLZ	M,37
IFN FTKI10!FTKL10,<
	PUSHJ	P,TSTREL##	;DON'T RELOCATE IF THIS IS A KI10
>
	TLO	M,R		;SETUP R IN LEFT HALF OF M FOR INDIRECTION
	HLRZ	T1,R		;SET T1 TO THE HIGHEST ADDRESS IN THE LOW SEGMENT
	CAIGE	T1,(M)		;IS THE ADDRESS IN THE LOW SEGMENT?
	JRST	STOHGH		;SEE IF HI SEG ADDRESS
IFN FTVM,<
	HRRZ	T1,M		;ADDRESS BEING STORED INTO
	CAML	T1,.UPMP+.UPHSS	;A HIGH SEGMENT ADDRESS?
	CAMLE	T1,.UPMP+.UPHSE	;NO
	CAIA
	JUMPN	T1,STOHGH	;NO, TRY THE HIGH SEGMENT
>
IFE FTVM,<
	HRRZ	T1,M		;SEE IF IT IS A LEGAL ADDRESS IN THE LOW SEGMENT
>
	CAIG	T1,JOBPFI##	;ADDRESS ABOVE THE JOB DATA AREA?
	TRNN	T1,777760	;OR IS IT IN THE USER'S AC'S?
	JRST	PUTWD2		;YES, OK TO STORE THE WORD
	SOS	-2(P)		;CAN'T STORE IN PROTECTED PART OF JOB DATA AREA
	JRST	PUTWD4
PUTWD2:
IFN FTKI10!FTKL10,<
	PUSHJ	P,TSTREL##	;SEE HOW TO RELOCATE
	JRST	PUTWD3		;KA10 OR SHADOW ACS
	EXCTXU	<MOVEM S,@M>	;STORE WORD IN USER'S AREA
	JRST	PUTWD4		;RESTORE AC AND RETURN
>
PUTWD3:	MOVEM	S,@M		;STORE WORD IN USER'S AREA
	JRST	PUTWD4		;RESTORE AC AND RETURN
STOHGH:	PUSH	P,T2		;SAVE T2
	PUSH	P,P2		;AND P2 SINCE HGHDEP DESTROYS THEM
	MOVE	T2,M		;HGHDEP WANTS WHERE TO STORE IN T2
	PUSHJ	P,HGHDEP##	;TRY TO DEPOSIT WORDS IN THE HIGH SEGMENT
	SOS	-4(P)		;CAN'T DO THAT, GIVE UP
	POP	P,P2		;RESTORE P2
	POP	P,T2		;AND T2
PUTWD4:	POP	P,T1		;AND T1
	POP	P,S		;AND S
	JRST	CPOPJ1##	;GIVE WIN RETURN
REPEAT	0,<
;ROUTINE TO REFERENCE A USER'S JOB DATA AREA AT ANY LEVEL
; EITHER SEGMENT
; CALLING SEQUENCE:
;
;	MOVE	J,JOB OR HIGH SEGMENT NUMBER ON KA10
;	SETUP PER PROCESS MAP AND USER BASE REGISTER ON KI10
;	PUSHJ	P,REFJDA
;	...	INSTRUCTION WHICH REFERENCES JOB DATA AREA
;	...	RETURN HERE IF INSTRUCTION DOES NOT SKIP
;	...	RETURN HERE IF INSTRUCTION SKIPS
;
; NOTE THAT THE INSTRUCTION CAN BE INDEXED AND/OR INDIRECTED
; BUT WOULD NOT NORMALLY HAVE R IN THE INDEX FIELD AS
; IN THE PAST.  THUS WHAT PREVIOUSLY WOULD HAVE BEEN
;
;	HRLZM	R,.JBREL(R)
;
; BECOMES
;
;	PUSHJ	P,REFJDA
;	  HRLZM	R,.JBREL
;NOTE:  AC S MUST BE AC 0
IFN FTKI10!FTKL10,<IFN FTMS,<

REFJDA::PUSH	P,S		;SAVE A WORKING AC
	MOVE	S,@-1(P)	;GET THE INSTRUCTION
	MOVEI	S,@S		;CALCULATE THE EFFECTIVE ADDRESS
	CAIG	S,.JBHDA##	;IS IT IN THE VESTIGUAL JOB DATA AREA?
	JRST	REFJD1		;YES
REFJD0:
IFN FTHALT,<
	CAIL	S,.JBDA##	;IS IT IN THE JOB DATA AREA?
	STOPCD	.,JOB##,OJA,	;++OUTSIDE JOBDAT AREA
>
	XCT	.C0AJD##	;NO, CALCULATE ITS ADDRESS IN EXEC
				; VIRTUAL MEMORY.  .C0AJD=ADD R,JBTADR(J)
				; ON A KA10 AND ADDI R,.JDAT ON A KI10.
	JRST	REFJD2		;GO DO THE MEMORY REFERENCE
REFJD1:	XCT	.C0AVD##	;CALCULATE EXEC VIRTUAL ADDRESS
REFJD2:	HLL	S,@-1(P)	;GET THE INSTRUCTION
	TLZ	S,37		;CLEAR INDEX AND INDIRECT SINCE ALREADY DONE
	MOVEM	S,1(P)		;SAVE IT
	POP	P,S		;RESTORE TEMPORARY SO IT CAN BE USED
				; IN THE EXECUTION OF THE INSTRUCTION
	XCT	2(P)		;DO IT
	JRST	CPOPJ1##	;SKIP THE INSTRUCTION AND RETURN
	JRST	CPOPJ2##	;THE INSTRUCTION SKIPPED SO DOUBLE SKIP RETURN

REFSGA::PUSH	P,S		;SAVE A WORKING AC
	MOVEI	S,@-1(P)	;GET THE INSTRUCTION
	MOVEI	S,@S		;CALCULATE THE EFFECTIVE ADDRESS
	JRST	REFJD0		;GO DO REFERENCE TO JOB DATA AREA
				; SINCE THAT IS WHERE SGA SYMBOLS
				; CURRENTLY ARE
>>	;END IFN <FTKI10!FTKL10>,FTMS CONDITIONAL
>	;END REPEAT 0
;SUBROUTINE TO CHECK IF SEGMENT # IN J IS A LEGAL SEG #
;ARGS	J=SEG#
;SKIP RETURN IF LEGAL SEGMENT #, NON-SKIP IF NOT


LGJSEG::HRRZ	T1,J
LGLSEG::CAILE	T1,JOBMAX##	;SKIP IF BELOW 1ST LEGAL SEG #
	CAIL	T1,JBTMAX##	;NO, SKIP IF LEGAL SEG #
	POPJ	P,
	JRST	CPOPJ1##

LGJPRC::SKIPA	T1,J		;FROM J, EXCLUDE ZERO
LGJPR1::SKIPA	T1,J		;FROM J, ALLOW ZERO
LGLPRC::JUMPLE	T1,CPOPJ##	;JUMP IF LE 0
LGLPR1::CAIG 	T1,JOBMAX##
	JUMPGE	T1,CPOPJ1##	;0 WAS ALREADY CHECKED
	POPJ	P,		;-N ALWAYS ILLEGAL
IFE FTPDBS,<
;SUBROUTINE TO CREATE A PDB
;ARG	J=JOB NUMBER


CREPDB::MOVEI	T2,PDB4WD##	;NUMBER OF 2 WORD BLOCKS NEEDED FOR A PDB
	PUSHJ	P,GET4WD##	;GET BLOCK FOR PDB
	  POPJ	P,		;CAN'T GET THRU
	HRRZ	W,T1
	HRRM	W,JBTPDB##(J)
	SETZM	(W)		;CLEAR ALL PDB
	HRLI	T1,1(W)		;MAKE BIT PTR
	MOVSS	T1
	BLT	T1,.PDLE4##-1(W)
	JRST	CPOPJ1##

;SUBROUTINE TO DEALLOCATE A PDB
;ARGS	J=JOB NUMBER

KILPDB::MOVEI	T1,PDB4WD##	;NUMBER OF 4 WORD BLOCKS FOR A PDB
	HRRZ	T2,JBTPDB##(J)	;ADDR OF PDB
	PUSHJ	P,GIV4WD##	;DEALLOCATE PDB
	HLLZS	JBTPDB##(J)	;CLEAR ADDR OF PDB
	POPJ	P,		;RETURN

IFN FTTRACK,<
;THE MAIN REASON SETPDB IS UNDER FTTRACK IS SO THAT THE SMALL MONITOR
;CAN LIVE WITHOUT SIXBIT .PDB. IN EACH PDB, SAVING THE WORD AND
;THIS ROUTINE.  THIS IS TEMPORARY FOR 5.04 ONLY;
;WHEN THE PDB IS SWAPPED THE WORD WILL BE NECESSARY AND THE CHECKS
;MUST BE REMOVED.  SEE COMCON AND SYSINI
;SUBROUTINE TO INITIALIZE A PDB
;ARG	W=ADDR OF PDB

SETPDB::HRRZ	T1,W		;ADDR OF PDB=DESTINATION
	HRLI	T1,PDBPRO##	;PROTOTYPE PDB=SOUTCE
	BLT	T1,.PDLE4-1(W)	;INITIALIZE PDB
	POPJ	P,		;EXIT
>
DATEND:	END
> ;END FTPDBS
DATEND:	END